--- /dev/null
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+#ifndef _IBSP_REGPATH_H_\r
+#define _IBSP_REGPATH_H_\r
+\r
+/* these definitions are common for installSP and WSD projects */\r
+#define IBSP_PM_REGISTRY_PATH \\r
+ TEXT("SYSTEM\\CurrentControlSet\\Services\\IBWSD\\")\r
+#define IBSP_PM_EVENTLOG_PATH \\r
+ TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\IBWSD")\r
+#define IBSP_PM_SUBKEY_NAME TEXT("IBWSD")\r
+#define IBSP_PM_SUBKEY_PERF TEXT("Performance")\r
+#define IBSP_PM_INI_FILE "ibsp_perfcounters.ini"\r
+#define IBSP_PM_SYM_H_FILE "ibsp_perfini.h"\r
+\r
+\r
+enum IBSP_PM_COUNTERS\r
+{\r
+ BYTES_SEND = 0,\r
+ BYTES_RECV,\r
+ BYTES_WRITE,\r
+ BYTES_READ,\r
+ BYTES_TOTAL,\r
+ COMP_SEND,\r
+ COMP_RECV,\r
+ COMP_TOTAL,\r
+ INTR_TOTAL,\r
+ IBSP_PM_NUM_COUNTERS\r
+\r
+};\r
+\r
+\r
+/* counter symbol names */\r
+#define IBSP_PM_OBJ 0\r
+#define IBSP_PM_COUNTER( X ) ((X + 1) * 2)\r
+\r
+#endif /* _IBSP_REGPATH_H_ */\r
UMTYPE=console\r
USE_CRTDLL=1\r
\r
+INCLUDES=..\..\..\inc;\\r
+ ..\..\..\inc\user;\\r
+ $(PLATFORM_SDK_PATH)\include;\r
+\r
SOURCES=\\r
installsp.c\r
\r
+USER_C_FLAGS=$(USER_C_FLAGS) -DPERFMON_ENABLED\r
+\r
TARGETLIBS=\\r
- $(SDK_LIB_PATH)\ws2_32.lib\r
+ $(SDK_LIB_PATH)\ws2_32.lib \\r
+ $(SDK_LIB_PATH)\LoadPerf.lib \r
\r
MSC_WARNING_LEVEL= /W3\r
\r
#include <stdio.h>\r
\r
/* Initialize the LSP's provider path for Infiband Service Provider dll */\r
-static const WCHAR *provider_path = L"%SYSTEMROOT%\\system32\\ibwsd.dll";\r
-static const WCHAR *provider_name = L"OpenIB Winsock Direct for InfiniBand";\r
-static const char *winsock_key_path = "System\\CurrentControlSet\\Services\\Winsock\\Parameters\\TCP on SAN";\r
-static const char *openib_key_name = "OpenIB Alliance";\r
+static const WCHAR provider_path[] = L"%SYSTEMROOT%\\system32\\ibwsd.dll";\r
+static const WCHAR provider_name[] = L"OpenIB Winsock Direct for InfiniBand";\r
+static const char winsock_key_path[] =\r
+ "System\\CurrentControlSet\\Services\\Winsock\\Parameters\\TCP on SAN";\r
+static const char openib_key_name[] = "OpenIB Alliance";\r
\r
/* Unique provider GUID generated with "uuidgen -s" */\r
static GUID provider_guid = {\r
#define WSCInstallProvider WSCInstallProvider64_32\r
#endif /* _WIN64 */\r
\r
+#ifdef PERFMON_ENABLED\r
+#include <Loadperf.h>\r
+#include "wsd/ibsp_regpath.h"\r
+\r
+\r
+typedef struct _pm_symbol_def\r
+{\r
+ DWORD name_def;\r
+ CHAR name_str[40];\r
+ CHAR name_desc[40];\r
+ CHAR help_desc[256];\r
+\r
+} pm_symbol_def_t;\r
+\r
+static pm_symbol_def_t _pm_symbols[]=\r
+{\r
+ { IBSP_PM_OBJ,\r
+ "IBSP_PM_OBJ",\r
+ "IB Winsock Direct",\r
+ "InfiniBand Windows Sockets Direct Provider."\r
+ },\r
+ { IBSP_PM_COUNTER(BYTES_SEND),\r
+ "IBSP_PM_BYTES_TX_SEC",\r
+ "Send bytes/sec",\r
+ "Send bytes/second, excluding RDMA Write."\r
+ },\r
+ { IBSP_PM_COUNTER(BYTES_RECV),\r
+ "IBSP_PM_BYTES_RX_SEC",\r
+ "Recv bytes/sec",\r
+ "Receive bytes/second, excluding RDMA Read."\r
+ },\r
+ { IBSP_PM_COUNTER(BYTES_WRITE),\r
+ "IBSP_PM_RDMA_WR_SEC",\r
+ "RDMA Write bytes/sec",\r
+ "RDMA Write bytes/second."\r
+ },\r
+ { IBSP_PM_COUNTER(BYTES_READ),\r
+ "IBSP_PM_RDMA_RD_SEC",\r
+ "RDMA Read bytes/sec",\r
+ "RDMA Read bytes/second."\r
+ },\r
+ { IBSP_PM_COUNTER(BYTES_TOTAL),\r
+ "IBSP_PM_BYTES_SEC",\r
+ "Total bytes/sec",\r
+ "Total bytes transmitted per second, including send, "\r
+ "receive, RDMA Write, and RDMA Read."\r
+ },\r
+ { IBSP_PM_COUNTER(COMP_SEND),\r
+ "IBSP_PM_SEND_COMPLETIONS_SEC",\r
+ "Send Completions/sec",\r
+ "Send and RDMA Write Completions/sec."\r
+ },\r
+ { IBSP_PM_COUNTER(COMP_RECV),\r
+ "IBSP_PM_RECV_COMPLETIONS_SEC",\r
+ "Recv Completions/sec",\r
+ "Recv and RDMA Read Completions/sec."\r
+ },\r
+ { IBSP_PM_COUNTER(COMP_TOTAL),\r
+ "IBSP_PM_COMPLETIONS_SEC",\r
+ "Total Completions/sec",\r
+ "Total Completions processed per second."\r
+ },\r
+ { IBSP_PM_COUNTER(INTR_TOTAL),\r
+ "IBSP_PM_COMPLETIONS_INTR",\r
+ "Total Interrupts/sec",\r
+ "Completion Queue events per second."\r
+ }\r
+};\r
+\r
+#define IBSP_PM_NUM_SYMBOLS (sizeof(_pm_symbols)/sizeof(pm_symbol_def_t))\r
+#define IBSP_PM_LANGUAGE "009" /* good for English */\r
+\r
+\r
+static DWORD\r
+_IBSPPerfmonIniFilesGenerate( void )\r
+{\r
+ FILE *f_handle;\r
+ DWORD num;\r
+\r
+ /* create ".h" file first */\r
+ f_handle = fopen( IBSP_PM_SYM_H_FILE, "w+" );\r
+\r
+ if( !f_handle )\r
+ {\r
+ fprintf(\r
+ stderr, "Create Header file %s failed\n", IBSP_PM_SYM_H_FILE );\r
+ return ERROR_FILE_INVALID;\r
+ }\r
+\r
+ fprintf(\r
+ f_handle, "/* %s Generated by program */ \r\n", IBSP_PM_SYM_H_FILE );\r
+ \r
+ \r
+ for( num = 0; num < IBSP_PM_NUM_SYMBOLS; num++ )\r
+ {\r
+ fprintf( f_handle, "#define\t%s\t%d\r\n",\r
+ _pm_symbols[num].name_str, _pm_symbols[num].name_def );\r
+ }\r
+\r
+ fflush( f_handle );\r
+ fclose( f_handle );\r
+\r
+ /* create 'ini' file next */\r
+ f_handle = fopen( IBSP_PM_INI_FILE, "w+" );\r
+\r
+ if( !f_handle )\r
+ {\r
+ fprintf( stderr, "Create INI file %s failed\n", IBSP_PM_INI_FILE );\r
+ return ERROR_FILE_INVALID;\r
+ }\r
+ \r
+ fprintf( f_handle, "[info]\r\ndrivername=" IBSP_PM_SUBKEY_NAME\r
+ "\r\nsymbolfile=" IBSP_PM_SYM_H_FILE "\r\n\r\n" );\r
+ fprintf( f_handle,"[languages]\r\n" IBSP_PM_LANGUAGE\r
+ "=language" IBSP_PM_LANGUAGE "\r\n\r\n" );\r
+\r
+ fprintf( f_handle, \r
+ "[objects]\r\n%s_" IBSP_PM_LANGUAGE "_NAME=%s\r\n\r\n[text]\r\n",\r
+ _pm_symbols[0].name_str, _pm_symbols[0].name_desc );\r
+ \r
+ for( num = 0; num < IBSP_PM_NUM_SYMBOLS; num++ )\r
+ {\r
+ fprintf( f_handle,"%s_" IBSP_PM_LANGUAGE "_NAME=%s\r\n",\r
+ _pm_symbols[num].name_str, _pm_symbols[num].name_desc );\r
+ fprintf( f_handle,"%s_" IBSP_PM_LANGUAGE "_HELP=%s\r\n",\r
+ _pm_symbols[num].name_str, _pm_symbols[num].help_desc );\r
+ }\r
+\r
+ fflush( f_handle );\r
+ fclose( f_handle );\r
+\r
+ return ERROR_SUCCESS;\r
+}\r
+\r
+\r
+static void\r
+_IBSPPerfmonIniFilesRemove( void )\r
+{\r
+ if( !DeleteFile( IBSP_PM_INI_FILE ) )\r
+ {\r
+ fprintf( stderr, "Delete file %s failed status %d\n",\r
+ IBSP_PM_INI_FILE, GetLastError() );\r
+ }\r
+ if( !DeleteFile( IBSP_PM_SYM_H_FILE ) )\r
+ {\r
+ fprintf( stderr,"Delete file %s failed status %d\n",\r
+ IBSP_PM_SYM_H_FILE, GetLastError() );\r
+ }\r
+}\r
+\r
+\r
+/* Try to create IB WSD Performance Register Keys */\r
+static LONG\r
+_IBSPPerfmonRegisterKeys( void )\r
+{\r
+ LONG reg_status;\r
+ HKEY pm_hkey;\r
+ DWORD typesSupp = 7;\r
+\r
+ reg_status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,\r
+ IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF, 0, NULL,\r
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &pm_hkey, NULL );\r
+\r
+ if( reg_status != ERROR_SUCCESS )\r
+ {\r
+ fprintf( stderr,\r
+ "_IBSPPerfmonRegisterKeys Create Key %s failed with %d\n",\r
+ IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF, reg_status );\r
+ return reg_status;\r
+ }\r
+\r
+ /* create/assign values to the key */\r
+ RegSetValueExW( pm_hkey, L"Library", 0, REG_EXPAND_SZ,\r
+ (LPBYTE)provider_path, sizeof(provider_path) );\r
+\r
+ RegSetValueEx( pm_hkey, TEXT("Open"), 0, REG_SZ,\r
+ (LPBYTE)TEXT("IBSPPmOpen"), sizeof(TEXT("IBSPPmOpen")) );\r
+\r
+ RegSetValueEx( pm_hkey, TEXT("Collect"), 0, REG_SZ,\r
+ (LPBYTE)TEXT("IBSPPmCollectData"), sizeof(TEXT("IBSPPmCollectData")) );\r
+\r
+ RegSetValueEx( pm_hkey, TEXT("Close"), 0, REG_SZ,\r
+ (LPBYTE)TEXT("IBSPPmClose"), sizeof(TEXT("IBSPPmClose")) );\r
+\r
+ RegFlushKey( pm_hkey );\r
+ RegCloseKey( pm_hkey );\r
+\r
+ reg_status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,\r
+ IBSP_PM_EVENTLOG_PATH, 0, NULL,\r
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &pm_hkey, NULL );\r
+\r
+ if( reg_status != ERROR_SUCCESS )\r
+ {\r
+ fprintf(stderr, "Create EventLog Key failed with %d\n", reg_status );\r
+ return reg_status;\r
+ }\r
+\r
+ /* create/assign values to the key */\r
+ RegSetValueExW( pm_hkey, L"EventMessageFile", 0, REG_EXPAND_SZ,\\r
+ (LPBYTE)provider_path, sizeof(provider_path) );\r
+\r
+ RegSetValueEx( pm_hkey, TEXT("TypesSupported"), 0, REG_DWORD,\r
+ (LPBYTE)&typesSupp, sizeof(typesSupp) );\r
+\r
+ RegFlushKey( pm_hkey );\r
+ RegCloseKey( pm_hkey );\r
+\r
+ return reg_status;\r
+}\r
+\r
+\r
+/* Try to destroy IB WSD Performance Register Keys */\r
+static LONG\r
+_IBSPPerfmonDeregisterKeys( void )\r
+{\r
+ LONG reg_status;\r
+\r
+ reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
+ IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF,\r
+ (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
+\r
+ if( reg_status != ERROR_SUCCESS )\r
+ {\r
+ fprintf( stderr,\r
+ "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
+ GetLastError() );\r
+ }\r
+\r
+ reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
+ IBSP_PM_REGISTRY_PATH, (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
+\r
+ if( reg_status != ERROR_SUCCESS )\r
+ {\r
+ fprintf( stderr,\r
+ "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
+ GetLastError() );\r
+ }\r
+\r
+ reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
+ IBSP_PM_EVENTLOG_PATH, (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
+\r
+ if( reg_status != ERROR_SUCCESS )\r
+ {\r
+ fprintf( stderr,\r
+ "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
+ GetLastError() );\r
+ }\r
+\r
+ return reg_status;\r
+}\r
+\r
+\r
+/*\r
+ * functions will try to register performance counters\r
+ * definitions with PerfMon application.\r
+ * API externally called by lodctr.exe/unlodctr.exe utilities.\r
+ */\r
+static DWORD\r
+_IBSPPerfmonRegisterCounters( void )\r
+{\r
+ DWORD status;\r
+ /*\r
+ * format commandline string, as per SDK :\r
+ * Pointer to a null-terminated string that consists of one or more \r
+ * arbitrary letters, a space, and then the name of the initialization\r
+ * file.\r
+ */\r
+ status = LoadPerfCounterTextStrings(\r
+ TEXT("unused ") TEXT(IBSP_PM_INI_FILE), TRUE );\r
+ if( status != ERROR_SUCCESS )\r
+ {\r
+ status = GetLastError();\r
+ fprintf( stderr,\r
+ "IBSPPerfmonRegisterCounters install failed status %d\n", status );\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+\r
+/*\r
+ * functions will try to unregister performance counters\r
+ * definitions with PerfMon application.\r
+ * API externally called by lodctr.exe/unlodctr.exe utilities.\r
+ */\r
+static DWORD\r
+_IBSPPerfmonDeregisterCounters( void )\r
+{\r
+ DWORD status;\r
+\r
+ /*\r
+ * format commandline string, as per SDK :\r
+ * Pointer to a null-terminated string that consists of one or more \r
+ * arbitrary letters, a space, and then the name of the initialization\r
+ * file.\r
+ */\r
+ status = UnloadPerfCounterTextStrings(\r
+ TEXT("unused ") TEXT(IBSP_PM_SUBKEY_NAME), TRUE );\r
+ if( status != ERROR_SUCCESS )\r
+ {\r
+ fprintf( stderr,\r
+ "IBSPPerfmonDeregisterCounters remove failed status %d\n",\r
+ status );\r
+ }\r
+ return status;\r
+}\r
+\r
+#endif /* PERFMON_ENABLED */\r
+\r
+\r
/*\r
* Function: usage\r
* Description: Prints usage information.\r
static void\r
usage (char *progname)\r
{\r
- printf ("usage: %s [-i/-r]\n", progname);\r
+ printf ("usage: %s [-i/-r [-p]]\n", progname);\r
printf (" -i Install the service provider\n"\r
" -r Remove the OpenIB service provider\n"\r
" -r <name> Remove the specified service provider\n"\r
HKEY hkey;\r
\r
/* Now setup the key. */\r
- reg_error = RegCreateKeyEx( HKEY_LOCAL_MACHINE, winsock_key_path, 0, NULL,\r
- REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL, &hkey, NULL );\r
+ reg_error = RegCreateKeyExA( HKEY_LOCAL_MACHINE, winsock_key_path,\r
+ 0, NULL, REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL,\r
+ &hkey, NULL );\r
if( reg_error == ERROR_SUCCESS )\r
{\r
- reg_error = RegSetValueEx( hkey, openib_key_name, 0, REG_BINARY,\r
+ reg_error = RegSetValueExA( hkey, openib_key_name, 0, REG_BINARY,\r
(PBYTE)&provider_guid, sizeof(GUID) );\r
if( reg_error == ERROR_SUCCESS )\r
{\r
HKEY hkey;\r
\r
/* Remove our key */\r
- reg_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,\r
+ reg_error = RegOpenKeyExA(HKEY_LOCAL_MACHINE,\r
winsock_key_path,\r
0,\r
(KEY_WRITE | KEY_READ),\r
&hkey);\r
if (reg_error == ERROR_SUCCESS) {\r
\r
- reg_error = RegDeleteValue(hkey, provider_name);\r
+ reg_error = RegDeleteValueA(hkey, provider_name);\r
if (reg_error == ERROR_SUCCESS) {\r
/* Force the system to remove the key now. */\r
RegFlushKey(hkey);\r
case 'i':\r
/* Install the Infiniband Service Provider */\r
install_provider ();\r
+#ifdef PERFMON_ENABLED\r
+ _IBSPPerfmonIniFilesGenerate();\r
+ if ( _IBSPPerfmonRegisterKeys() == ERROR_SUCCESS )\r
+ _IBSPPerfmonRegisterCounters();\r
+#endif\r
break;\r
\r
case 'r':\r
remove_provider( openib_key_name );\r
else\r
remove_provider( argv[2] );\r
+#ifdef PERFMON_ENABLED\r
+ _IBSPPerfmonIniFilesRemove();\r
+ if ( _IBSPPerfmonDeregisterCounters() == ERROR_SUCCESS )\r
+ _IBSPPerfmonDeregisterKeys();\r
+#endif\r
break;\r
\r
case 'l':\r
/* List existing providers */\r
print_providers();\r
break;\r
-\r
+ \r
default:\r
usage (argv[0]);\r
break;\r
ibspdll.c \\r
misc.c \\r
sockinfo.c \\r
- ibsp_duplicate.c\r
+ ibsp_duplicate.c \\r
+ ibsp_perfmon.c\r
\r
INCLUDES=..\..\..\inc;..\..\..\inc\user;$(DDK_INC_PATH);\r
\r
-USER_C_FLAGS=$(USER_C_FLAGS) -DCL_NO_TRACK_MEM\r
+USER_C_FLAGS=$(USER_C_FLAGS) -DCL_NO_TRACK_MEM -DPERFMON_ENABLED\r
\r
TARGETLIBS=\\r
$(SDK_LIB_PATH)\kernel32.lib \\r
$(SDK_LIB_PATH)\ws2_32.lib \\r
$(SDK_LIB_PATH)\rpcrt4.lib \\r
+ $(SDK_LIB_PATH)\Advapi32.lib \\r
+ $(SDK_LIB_PATH)\LoadPerf.lib \\r
!if $(FREEBUILD)\r
$(TARGETPATH)\*\complib.lib \\r
$(TARGETPATH)\*\ibal.lib\r
\r
#include "ibspdll.h"\r
\r
+#ifdef PERFMON_ENABLED\r
+#include "ibsp_perfmon.h"\r
+#endif\r
+\r
\r
typedef struct _io_comp_info\r
{\r
* NOTE: Without a valid length, the switch doesn't seem to call \r
* GetOverlappedResult() even if we call lpWPUCompleteOverlappedRequest()\r
*/\r
- if( wc->wc_type == IB_WC_RECV )\r
+ switch ( wc->wc_type ) \r
{\r
+ case IB_WC_RECV:\r
lpOverlapped->InternalHigh = wc->length;\r
-\r
#ifdef IBSP_LOGGING\r
cl_spinlock_acquire( &socket_info->recv_lock );\r
DataLogger_WriteData(&socket_info->RecvDataLogger,\r
wc->length);\r
cl_spinlock_release( &socket_info->recv_lock );\r
#endif\r
+#ifdef PERFMON_ENABLED\r
+ InterlockedIncrement64( &g_pm_stat.pdata[COMP_RECV] );\r
+ InterlockedExchangeAdd64( &g_pm_stat.pdata[BYTES_RECV],\r
+ lpOverlapped->InternalHigh );\r
+#endif\r
+ break;\r
+#ifdef PERFMON_ENABLED\r
+\r
+ case IB_WC_RDMA_READ:\r
+ lpOverlapped->InternalHigh = wc->length;\r
+ InterlockedIncrement64( &g_pm_stat.pdata[COMP_RECV] );\r
+ InterlockedExchangeAdd64( &g_pm_stat.pdata[BYTES_READ],\r
+ lpOverlapped->InternalHigh );\r
+ break;\r
+\r
+ case IB_WC_SEND:\r
+ InterlockedIncrement64( &g_pm_stat.pdata[COMP_SEND] );\r
+ InterlockedExchangeAdd64( &g_pm_stat.pdata[BYTES_SEND],\r
+ lpOverlapped->InternalHigh );\r
+ break;\r
+\r
+ case IB_WC_RDMA_WRITE:\r
+ InterlockedIncrement64( &g_pm_stat.pdata[COMP_SEND] );\r
+ InterlockedExchangeAdd64( &g_pm_stat.pdata[BYTES_WRITE],\r
+ lpOverlapped->InternalHigh );\r
+ default:\r
+ break;\r
}\r
\r
+#endif /* PERFMON_ENABLED */\r
+\r
lpOverlapped->OffsetHigh = 0;\r
break;\r
\r
break;\r
}\r
\r
+#ifdef PERFMON_ENABLED\r
+ InterlockedIncrement64( &g_pm_stat.pdata[COMP_TOTAL] );\r
+#endif\r
+\r
#ifdef _DEBUG_\r
if( wc->wc_type == IB_WC_RECV )\r
{\r
}\r
\r
if( wc->wc_type == IB_WC_RECV )\r
+ {\r
cl_atomic_dec( &socket_info->recv_cnt );\r
+ }\r
else\r
+ {\r
cl_atomic_dec( &socket_info->send_cnt );\r
+ }\r
\r
IBSP_EXIT( IBSP_DBG_IO );\r
}\r
\r
IBSP_ENTER( IBSP_DBG_HW );\r
\r
-\r
fzprint(("%s():%d:0x%x:0x%x: cq_tinfo=0x%p\n", __FUNCTION__,\r
__LINE__, GetCurrentProcessId(), GetCurrentThreadId(), cq_tinfo));\r
\r
fzprint(("%s():%d:0x%x:0x%x: Calling ib_cq_comp().\n", __FUNCTION__,\r
__LINE__, GetCurrentProcessId(), GetCurrentThreadId()));\r
\r
+#ifdef PERFMON_ENABLED\r
+ InterlockedIncrement64( &g_pm_stat.pdata[INTR_TOTAL] );\r
+#endif\r
i = g_max_poll;\r
do\r
{\r
--- /dev/null
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+\r
+#include <string.h>\r
+#include "ibspdebug.h"\r
+#include "ibsp_perfmon.h"\r
+\r
+\r
+struct _ibsp_pm_definition g_ibsp_pm_def; /* IB WSD performance object */\r
+\r
+\r
+void\r
+IBSPPmInit( void )\r
+{\r
+ HANDLE h_mapping;\r
+ BOOL just_created;\r
+ SECURITY_ATTRIBUTES sec_attr;\r
+\r
+ IBSP_ENTER( IBSP_DBG_PERFMON );\r
+\r
+ g_pm_stat.idx = INVALID_IDX;\r
+ g_pm_stat.p_shmem = NULL;\r
+\r
+ sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);\r
+ sec_attr.bInheritHandle = FALSE;\r
+\r
+ if( !ConvertStringSecurityDescriptorToSecurityDescriptor(\r
+ IBSP_PM_SEC_STRING, SDDL_REVISION_1,\r
+ &(sec_attr.lpSecurityDescriptor), NULL ) )\r
+ {\r
+ IBSP_ERROR( ("SecurityDescriptor error %d\n", GetLastError()) );\r
+ return;\r
+ }\r
+\r
+ h_mapping = CreateFileMapping(\r
+ INVALID_HANDLE_VALUE, // use paging file\r
+ &sec_attr, // security attributes\r
+ PAGE_READWRITE, // read/write access\r
+ 0, // size: high 32-bits\r
+ sizeof(pm_shmem_t), // size: low 32-bits\r
+ IBSP_PM_MAPPED_OBJ_NAME );\r
+\r
+ LocalFree( sec_attr.lpSecurityDescriptor );\r
+\r
+ if( h_mapping == NULL )\r
+ {\r
+ IBSP_ERROR_EXIT( ("CreateFileMapping error %d\n", GetLastError()) );\r
+ return;\r
+ }\r
+\r
+ just_created = (GetLastError() != ERROR_ALREADY_EXISTS);\r
+\r
+ /* Get a pointer to the shared memory. */\r
+ g_pm_stat.p_shmem = MapViewOfFile(\r
+ h_mapping, // object handle\r
+ FILE_MAP_ALL_ACCESS,\r
+ 0, // high offset: map from\r
+ 0, // low offset: beginning\r
+ 0); // num bytes to map\r
+\r
+ /* Now that we have the view mapped, we don't need the mapping handle. */\r
+ g_pm_stat.h_mapping = h_mapping;\r
+\r
+ if( g_pm_stat.p_shmem == NULL )\r
+ {\r
+ IBSP_ERROR( ("MapViewOfFile returned %d\n", GetLastError()) );\r
+ return;\r
+ }\r
+ \r
+ if( just_created )\r
+ {\r
+ /*\r
+ * Reserve instance 0 for fallback counters\r
+ * Apps that can't get a dedicated slot will share this one.\r
+ */\r
+ wcscpy( g_pm_stat.p_shmem->obj[0].app_name,\r
+ IBSP_PM_TOTAL_COUNTER_NAME );\r
+ g_pm_stat.p_shmem->obj[0].taken = 1;\r
+ }\r
+\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+}\r
+\r
+\r
+/*\r
+ * We always get a slot - either an individual one, or fall back on the \r
+ * common one.\r
+ */\r
+void\r
+IBSPPmGetSlot( void )\r
+{\r
+ WCHAR mod_path[MAX_PATH];\r
+ WCHAR* buf;\r
+ int idx;\r
+ size_t name_len;\r
+ WCHAR id_str[12];\r
+ mem_obj_t *p_slot;\r
+ pm_shmem_t* p_mem = g_pm_stat.p_shmem;\r
+\r
+ IBSP_ENTER( IBSP_DBG_PERFMON );\r
+\r
+ if( g_pm_stat.p_shmem == NULL )\r
+ {\r
+ g_pm_stat.pdata = g_pm_stat.fall_back_data;\r
+ return;\r
+ }\r
+\r
+ GetModuleFileNameW( NULL, mod_path, MAX_PATH );\r
+\r
+ buf = wcsrchr( mod_path, L'\\' );\r
+ if( !buf )\r
+ buf = mod_path;\r
+ else\r
+ buf++;\r
+\r
+ /* The max length is 11, one for the ':', and 10 for the process ID. */\r
+ id_str[0] = ':';\r
+ _ultow( GetCurrentProcessId(), &id_str[1], 10 );\r
+\r
+ /* Cap the length of the application. */\r
+ name_len = min( wcslen( buf ),\r
+ IBSP_PM_APP_NAME_SIZE - 1 - wcslen( id_str ) );\r
+\r
+ /* instance 0 is taken for "Total" counters, so don't try it */\r
+ for( idx = 1; idx < IBSP_PM_NUM_INSTANCES; idx++)\r
+ {\r
+ /* Compare with 0, exchange with 1 */\r
+ if( InterlockedCompareExchange(\r
+ &g_pm_stat.p_shmem->obj[idx].taken, 1, 0 ) )\r
+ {\r
+ continue;\r
+ }\r
+\r
+ p_slot = &g_pm_stat.p_shmem->obj[idx];\r
+\r
+ /* Copy the app name. */\r
+ CopyMemory( p_slot->app_name, buf, name_len * sizeof(WCHAR) );\r
+ CopyMemory( &p_slot->app_name[name_len], id_str,\r
+ (wcslen( id_str ) + 1) * sizeof(WCHAR) );\r
+\r
+ g_pm_stat.idx = idx;\r
+ g_pm_stat.pdata = g_pm_stat.p_shmem->obj[idx].data;\r
+ IBSP_TRACE2( IBSP_DBG_PERFMON,\r
+ ("%S got slot %d\n", p_slot->app_name, idx) );\r
+ break;\r
+ }\r
+ \r
+ if( idx == IBSP_PM_NUM_INSTANCES )\r
+ {\r
+ /*\r
+ * Assign "Total" slot for this process to avoid loosing precious\r
+ * statistic. Keep saved idx INVALID so data won't be flushed during\r
+ * process closeout.\r
+ */\r
+ g_pm_stat.pdata = p_mem->obj[0].data;\r
+ }\r
+ \r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+}\r
+\r
+\r
+void\r
+IBSPPmReleaseSlot( void )\r
+{\r
+ mem_obj_t *p_slot;\r
+ int idx;\r
+\r
+ /* perfmon never get registered itself in shared mem buffer */\r
+ if ( g_pm_stat.idx == INVALID_IDX )\r
+ return;\r
+\r
+ if( g_pm_stat.p_shmem == NULL )\r
+ return;\r
+\r
+ p_slot = &g_pm_stat.p_shmem->obj[g_pm_stat.idx];\r
+\r
+ /* Add all the data to the "Total" bin (0) */\r
+ for( idx = 0; idx < IBSP_PM_NUM_COUNTERS; idx++ )\r
+ {\r
+ InterlockedExchangeAdd64( &g_pm_stat.p_shmem->obj[0].data[idx],\r
+ InterlockedExchange64( &g_pm_stat.pdata[idx], 0 ) );\r
+ }\r
+ ZeroMemory( p_slot->app_name, sizeof(p_slot->app_name) );\r
+ InterlockedExchange( &p_slot->taken, 0 );\r
+\r
+ g_pm_stat.idx = INVALID_IDX;\r
+\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+}\r
+\r
+\r
+static BOOL\r
+__PmIsQuerySupported(\r
+ IN WCHAR* p_query_str )\r
+{\r
+ if( p_query_str == NULL )\r
+ return TRUE;\r
+\r
+ if( *p_query_str == 0 )\r
+ return TRUE;\r
+\r
+ if( wcsstr( p_query_str, L"Global" ) != NULL )\r
+ return TRUE;\r
+\r
+ if( wcsstr( p_query_str, L"Foreign" ) != NULL )\r
+ return FALSE;\r
+\r
+ if( wcsstr( p_query_str, L"Costly" ) != NULL )\r
+ return FALSE;\r
+\r
+ else\r
+ return TRUE;\r
+}\r
+\r
+\r
+/*\r
+ * http://msdn.microsoft.com/library/en-us/perfctrs/perf/openperformancedata.asp\r
+ */\r
+DWORD APIENTRY\r
+IBSPPmOpen(\r
+ IN LPWSTR lpDeviceNames )\r
+{\r
+ DWORD status = ERROR_SUCCESS;\r
+ HKEY pm_hkey = NULL;\r
+ DWORD data_size;\r
+ DWORD data_type;\r
+ DWORD first_counter = 0;\r
+ DWORD first_help = 0;\r
+ int num = 0;\r
+ int num_offset;\r
+\r
+ IBSP_ENTER( IBSP_DBG_PERFMON );\r
+\r
+ UNUSED_PARAM(lpDeviceNames);\r
+\r
+ if( g_pm_stat.threads++ )\r
+ {\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+ return ERROR_SUCCESS;\r
+ }\r
+\r
+ /* open Registry and query for the first and last keys */\r
+ status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,\r
+ IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF,\r
+ 0L, KEY_READ, &pm_hkey);\r
+\r
+ if( status != ERROR_SUCCESS )\r
+ {\r
+ g_pm_stat.threads--;\r
+ IBSP_ERROR_EXIT(\r
+ ("RegOpenKeyEx for perf information returned %d.\n", status) );\r
+ return status;\r
+ }\r
+\r
+ data_size = sizeof(DWORD);\r
+ status = RegQueryValueEx( pm_hkey, "First Counter", 0L,\r
+ &data_type, (LPBYTE)&first_counter, &data_size );\r
+\r
+ if( status != ERROR_SUCCESS )\r
+ {\r
+ RegCloseKey(pm_hkey);\r
+ g_pm_stat.threads--;\r
+ IBSP_ERROR_EXIT(\r
+ ("RegQueryValueEx for \"First Counter\" returned %d.\n", status) );\r
+ return status;\r
+ }\r
+\r
+ data_size = sizeof(DWORD);\r
+ status = RegQueryValueEx( pm_hkey, "First Help", 0L,\r
+ &data_type, (LPBYTE)&first_help, &data_size );\r
+\r
+ RegCloseKey( pm_hkey );\r
+\r
+ if( status != ERROR_SUCCESS )\r
+ {\r
+ g_pm_stat.threads--;\r
+ IBSP_ERROR_EXIT(\r
+ ("RegQueryValueEx for \"First Help\" returned %d.\n", status) );\r
+ return status;\r
+ }\r
+\r
+ /* perf_obj */ \r
+ g_ibsp_pm_def.perf_obj.ObjectNameTitleIndex = IBSP_PM_OBJ + first_counter;\r
+ g_ibsp_pm_def.perf_obj.ObjectHelpTitleIndex = IBSP_PM_OBJ + first_help;\r
+ g_ibsp_pm_def.perf_obj.TotalByteLength =\r
+ sizeof(ibsp_pm_definition_t) + sizeof(ibsp_pm_counters_t);\r
+ g_ibsp_pm_def.perf_obj.DefinitionLength = sizeof(ibsp_pm_definition_t);\r
+ g_ibsp_pm_def.perf_obj.HeaderLength = sizeof(PERF_OBJECT_TYPE);\r
+\r
+ g_ibsp_pm_def.perf_obj.ObjectNameTitle = 0;\r
+ g_ibsp_pm_def.perf_obj.ObjectHelpTitle = 0;\r
+\r
+ g_ibsp_pm_def.perf_obj.DetailLevel = PERF_DETAIL_NOVICE;\r
+ g_ibsp_pm_def.perf_obj.NumCounters = IBSP_PM_NUM_COUNTERS;\r
+ g_ibsp_pm_def.perf_obj.DefaultCounter = 0;\r
+ g_ibsp_pm_def.perf_obj.NumInstances = 0;\r
+ g_ibsp_pm_def.perf_obj.CodePage = 0;\r
+\r
+ QueryPerformanceFrequency( &g_ibsp_pm_def.perf_obj.PerfFreq );\r
+\r
+ /* initialize all counter definitions */\r
+ num_offset = IBSP_PM_OBJ + 2;\r
+ for ( num = 0; num < IBSP_PM_NUM_COUNTERS ; num++, num_offset += 2)\r
+ {\r
+ g_ibsp_pm_def.counter[num].CounterNameTitleIndex = num_offset + first_counter;\r
+ g_ibsp_pm_def.counter[num].CounterHelpTitleIndex = num_offset + first_help;\r
+ g_ibsp_pm_def.counter[num].ByteLength = sizeof(PERF_COUNTER_DEFINITION);\r
+ g_ibsp_pm_def.counter[num].CounterNameTitle = 0;\r
+ g_ibsp_pm_def.counter[num].CounterHelpTitle = 0;\r
+ g_ibsp_pm_def.counter[num].DefaultScale = 0;\r
+ g_ibsp_pm_def.counter[num].DetailLevel = PERF_DETAIL_NOVICE;\r
+ g_ibsp_pm_def.counter[num].CounterType = PERF_COUNTER_BULK_COUNT;\r
+ /* All counters should be kept to 64-bits for consistency and simplicity. */\r
+ g_ibsp_pm_def.counter[num].CounterSize = sizeof(LONG64);\r
+ g_ibsp_pm_def.counter[num].CounterOffset =\r
+ (DWORD)offsetof( ibsp_pm_counters_t, data[num] );\r
+ }\r
+\r
+ g_pm_stat.h_evlog = RegisterEventSource( NULL, IBSP_PM_SUBKEY_NAME );\r
+ if( !g_pm_stat.h_evlog )\r
+ {\r
+ g_pm_stat.threads--;\r
+ status = GetLastError();\r
+ IBSP_ERROR_EXIT( ("RegisterEventSource failed with %d\n", status) );\r
+ return status;\r
+ }\r
+\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+ return ERROR_SUCCESS;\r
+}\r
+\r
+\r
+/*\r
+ * http://msdn.microsoft.com/library/en-us/perfctrs/perf/closeperformancedata.asp\r
+ */\r
+DWORD APIENTRY\r
+IBSPPmClose( void )\r
+{\r
+ BOOL status;\r
+\r
+ IBSP_ENTER( IBSP_DBG_PERFMON );\r
+\r
+ if( --g_pm_stat.threads )\r
+ {\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+ return ERROR_SUCCESS;\r
+ }\r
+\r
+ IBSPPmReleaseSlot();\r
+\r
+ /* avoid double closing */\r
+ if( g_pm_stat.p_shmem != NULL )\r
+ {\r
+ status = UnmapViewOfFile( g_pm_stat.p_shmem );\r
+ g_pm_stat.p_shmem = NULL;\r
+ }\r
+ \r
+ if( g_pm_stat.h_evlog != NULL )\r
+ {\r
+ DeregisterEventSource( g_pm_stat.h_evlog );\r
+ g_pm_stat.h_evlog = NULL;\r
+ }\r
+\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+ return ERROR_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/*\r
+ * http://msdn.microsoft.com/library/en-us/perfctrs/perf/collectperformancedata.asp\r
+ */\r
+DWORD WINAPI\r
+IBSPPmCollectData(\r
+ IN LPWSTR lpValueName,\r
+ IN OUT LPVOID* lppData,\r
+ IN OUT LPDWORD lpcbTotalBytes,\r
+ IN OUT LPDWORD lpNumObjectTypes )\r
+{\r
+ int32_t sh_num;\r
+ int32_t num_instances, max_instances;\r
+ uint32_t use_bytes;\r
+ ibsp_pm_definition_t *p_obj_def;\r
+ ibsp_pm_counters_t *p_count_def;\r
+ PERF_INSTANCE_DEFINITION *p_inst_def;\r
+ pm_shmem_t *p_mem;\r
+ LONG64 total_data[IBSP_PM_NUM_COUNTERS];\r
+ \r
+ IBSP_ENTER( IBSP_DBG_PERFMON );\r
+\r
+ p_mem = (pm_shmem_t * __ptr64 )g_pm_stat.p_shmem;\r
+ \r
+ if( p_mem == NULL )\r
+ {\r
+ IBSP_ERROR( ("No shared memory object\n") );\r
+ goto done;\r
+ }\r
+\r
+ if( !__PmIsQuerySupported(lpValueName ) )\r
+ {\r
+ IBSP_TRACE1( IBSP_DBG_PERFMON, ("Unsupported query\n") );\r
+ goto done;\r
+ }\r
+\r
+ if( !g_pm_stat.threads )\r
+ {\r
+ IBSP_ERROR( ("Initialization was not completed\n") );\r
+done:\r
+ *lpcbTotalBytes = 0;\r
+ *lpNumObjectTypes = 0;\r
+\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+ return ERROR_SUCCESS;\r
+ }\r
+\r
+ ZeroMemory( &total_data, sizeof(total_data) );\r
+ num_instances = 0;\r
+ /* sum total counters that were not filled in completion routine */\r
+ for( sh_num = 0; sh_num < IBSP_PM_NUM_INSTANCES; sh_num++ )\r
+ {\r
+ if( !InterlockedCompareExchange( &p_mem->obj[sh_num].taken, 1, 1 ) )\r
+ continue;\r
+\r
+ total_data[BYTES_SEND] += p_mem->obj[sh_num].data[BYTES_SEND];\r
+ total_data[BYTES_RECV] += p_mem->obj[sh_num].data[BYTES_RECV];\r
+ total_data[BYTES_WRITE] += p_mem->obj[sh_num].data[BYTES_WRITE];\r
+ total_data[BYTES_READ] += p_mem->obj[sh_num].data[BYTES_READ];\r
+ /* Update total for current slot. */\r
+ p_mem->obj[sh_num].data[BYTES_TOTAL] =\r
+ p_mem->obj[sh_num].data[BYTES_SEND] +\r
+ p_mem->obj[sh_num].data[BYTES_RECV] +\r
+ p_mem->obj[sh_num].data[BYTES_WRITE] +\r
+ p_mem->obj[sh_num].data[BYTES_READ];\r
+ total_data[BYTES_TOTAL] += p_mem->obj[sh_num].data[BYTES_TOTAL];\r
+ total_data[COMP_SEND] += p_mem->obj[sh_num].data[COMP_SEND];\r
+ total_data[COMP_RECV] += p_mem->obj[sh_num].data[COMP_RECV];\r
+ total_data[COMP_TOTAL] += p_mem->obj[sh_num].data[COMP_TOTAL];\r
+ total_data[INTR_TOTAL] += p_mem->obj[sh_num].data[INTR_TOTAL];\r
+\r
+ num_instances++;\r
+ }\r
+\r
+ IBSP_TRACE1( IBSP_DBG_PERFMON, ("%d instances.\n", num_instances) );\r
+\r
+ /* calc buffer size required for data return */\r
+ use_bytes = sizeof(ibsp_pm_definition_t) + \\r
+ (sizeof(PERF_INSTANCE_DEFINITION) + \\r
+ sizeof(ibsp_pm_counters_t) + \\r
+ (sizeof(WCHAR) * IBSP_PM_APP_NAME_SIZE)) * num_instances;\r
+\r
+ if( *lpcbTotalBytes < use_bytes )\r
+ {\r
+ *lpcbTotalBytes = 0;\r
+ *lpNumObjectTypes = 0;\r
+ return ERROR_MORE_DATA;\r
+ }\r
+\r
+ p_obj_def = (ibsp_pm_definition_t*)*lppData;\r
+ use_bytes = sizeof(ibsp_pm_definition_t);\r
+\r
+ /* Copy counter definition */\r
+ CopyMemory( p_obj_def, &g_ibsp_pm_def, sizeof(ibsp_pm_definition_t) );\r
+\r
+ p_obj_def->perf_obj.NumInstances = num_instances;\r
+ QueryPerformanceCounter( &p_obj_def->perf_obj.PerfTime );\r
+\r
+ max_instances = num_instances;\r
+\r
+ /* Assign pointers for the first instance */\r
+ p_inst_def = (PERF_INSTANCE_DEFINITION*)(p_obj_def + 1);\r
+\r
+ for( sh_num = 0; sh_num < IBSP_PM_NUM_INSTANCES; sh_num++ )\r
+ {\r
+ if( !InterlockedCompareExchange( &p_mem->obj[sh_num].taken, 1, 1 ) )\r
+ continue;\r
+\r
+ /* Make sure we don't overrun the buffer! */\r
+ if( max_instances-- == 0 )\r
+ break;\r
+\r
+ p_inst_def->ByteLength = sizeof(PERF_INSTANCE_DEFINITION) + \r
+ (sizeof(WCHAR) * IBSP_PM_APP_NAME_SIZE);\r
+ p_inst_def->ParentObjectTitleIndex = 0;\r
+ p_inst_def->ParentObjectInstance = 0;\r
+ p_inst_def->UniqueID = -1; /* using module names */\r
+ p_inst_def->NameOffset = sizeof(PERF_INSTANCE_DEFINITION);\r
+\r
+ /* Length in bytes of Unicode name string, including terminating NULL */\r
+ p_inst_def->NameLength =\r
+ (DWORD)wcslen( p_mem->obj[sh_num].app_name ) + 1;\r
+ p_inst_def->NameLength *= sizeof(WCHAR);\r
+\r
+ CopyMemory( (WCHAR*)(p_inst_def + 1),\r
+ p_mem->obj[sh_num].app_name, p_inst_def->NameLength );\r
+\r
+ use_bytes += p_inst_def->ByteLength;\r
+\r
+ /* advance to counter definition */\r
+ p_count_def = (ibsp_pm_counters_t*)\r
+ (((BYTE*)p_inst_def) + p_inst_def->ByteLength);\r
+\r
+ p_count_def->pm_block.ByteLength = sizeof(ibsp_pm_counters_t);\r
+ use_bytes += sizeof(ibsp_pm_counters_t);\r
+\r
+ /* Here we report actual counter values. */\r
+ if( sh_num == 0 )\r
+ {\r
+ CopyMemory( p_count_def->data, total_data, sizeof(total_data) );\r
+ }\r
+ else\r
+ {\r
+ CopyMemory( p_count_def->data, p_mem->obj[sh_num].data,\r
+ sizeof(p_mem->obj[sh_num].data) );\r
+ }\r
+\r
+ /* Advance pointers for the next instance definition */\r
+ p_inst_def = (PERF_INSTANCE_DEFINITION*)(p_count_def + 1);\r
+ }\r
+\r
+ p_obj_def->perf_obj.TotalByteLength = (DWORD)use_bytes;\r
+\r
+ *lppData = ((BYTE*)*lppData) + use_bytes;\r
+ *lpNumObjectTypes = 1;\r
+ *lpcbTotalBytes = (DWORD)use_bytes;\r
+\r
+ IBSP_EXIT( IBSP_DBG_PERFMON );\r
+ return ERROR_SUCCESS;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+#ifndef _IBSP_PERFMON_H_\r
+#define _IBSP_PERFMON_H_\r
+\r
+\r
+#include <sddl.h>\r
+#include <winperf.h>\r
+#include "wsd/ibsp_regpath.h"\r
+\r
+\r
+/* invalid instance index value to initialize */\r
+#define INVALID_IDX 0xffffffff\r
+\r
+#define IBSP_PM_SEC_STRING \\r
+ TEXT("D:(A;CIOI;GAFA;;;SY)" /* SDDL_LOCAL_SYSTEM */ \\r
+ "(A;CIOI;GAFA;;;DA)" /* SDDL_DOMAIN_ADMIN */ \\r
+ "(A;CIOI;GAFA;;;BA)" /* SDDL_BUILTIN_ADMIN */ \\r
+ "(A;CIOI;GAFA;;;NS)" /* SDDL_NETWORK_SERVICE */ \\r
+ "(A;CIOI;GAFA;;;LS)" /* SDDL_LOCAL_SERVICE */ \\r
+ "(A;CIOI;GAFA;;;SU)" /* SDDL_SERVICE */ \\r
+ "(A;CIOI;GAFA;;;MU)" /* SDDL_PERFMON_USERS */ \\r
+ "(A;CIOI;GAFA;;;LU)") /* SDDL_PERFLOG_USERS */\r
+\r
+#define IBSP_PM_NUM_OBJECT_TYPES 1\r
+#define IBSP_PM_NUM_INSTANCES 100 /* how many processes we can handle */\r
+\r
+#define IBSP_PM_APP_NAME_SIZE 24 /* Must be multiple of 8 */\r
+#define IBSP_PM_TOTAL_COUNTER_NAME L"_Total"\r
+#define IBSP_PM_MAPPED_OBJ_NAME TEXT("Global\\ibwsd_perfmon_data")\r
+\r
+\r
+/* Structures used to report counter information to perfmon. */\r
+typedef struct _ibsp_pm_definition\r
+{\r
+ PERF_OBJECT_TYPE perf_obj;\r
+ PERF_COUNTER_DEFINITION counter[IBSP_PM_NUM_COUNTERS];\r
+\r
+} ibsp_pm_definition_t;\r
+\r
+typedef struct _ibsp_pm_counters\r
+{\r
+ PERF_COUNTER_BLOCK pm_block;\r
+ LONG64 data[IBSP_PM_NUM_COUNTERS];\r
+\r
+} ibsp_pm_counters_t;\r
+\r
+\r
+/* Structures used to manage counters internally */\r
+typedef struct _mem_obj\r
+{\r
+ volatile LONG taken;\r
+ WCHAR app_name[IBSP_PM_APP_NAME_SIZE];\r
+ LONG64 data[IBSP_PM_NUM_COUNTERS];\r
+\r
+} mem_obj_t;\r
+\r
+typedef struct _pm_shmem\r
+{\r
+ mem_obj_t obj[IBSP_PM_NUM_INSTANCES];\r
+\r
+} pm_shmem_t;\r
+\r
+\r
+/* global data for every process linked to this DLL */\r
+struct _pm_stat\r
+{\r
+ struct _pm_shmem* p_shmem; /* base pointer to shared memory for this process */\r
+ volatile LONG64* pdata; /* pointer to data collected */\r
+ HANDLE h_mapping;\r
+ HANDLE h_evlog; /* event log handle */\r
+ DWORD threads; /* number of threads open */\r
+ DWORD idx; /* slot index assigned for this process */\r
+ LONG64 fall_back_data[IBSP_PM_NUM_COUNTERS];\r
+\r
+} g_pm_stat;\r
+\r
+\r
+void\r
+IBSPPmInit( void );\r
+\r
+DWORD APIENTRY\r
+IBSPPmClose( void );\r
+\r
+void\r
+IBSPPmGetSlot( void );\r
+\r
+void\r
+IBSPPmReleaseSlot( void );\r
+\r
+#endif /* _IBSP_PERFMON_H_ */\r
#define IBSP_DBG_HW 0x00000800 /* Hardware */\r
#define IBSP_DBG_IO 0x00001000 /* Overlapped I/O request */\r
#define IBSP_DBG_DUP 0x00002000 /* Socket Duplication */\r
+#define IBSP_DBG_PERFMON 0x00004000 /* Performance Monitoring */\r
\r
#define IBSP_DBG_LEVEL4 0x01000000 /* debug use */\r
#define IBSP_DBG_LEVEL3 0x02000000 /* debug use */\r
*\r
* $Id$\r
*/\r
-\r
#include <tchar.h>\r
#include <stdlib.h>\r
#include "ibspdll.h"\r
\r
+#ifdef PERFMON_ENABLED\r
+#include "ibsp_perfmon.h"\r
+#endif /* PERFMON_ENABLED */\r
+\r
/* Globals */\r
struct ibspdll_globals g_ibsp;\r
\r
uint32_t g_max_inline = 0xFFFFFFFF;\r
uint32_t g_max_poll = 0;\r
\r
+\r
/*\r
* Function: DllMain\r
* \r
\r
if( init_globals() )\r
return FALSE;\r
+\r
+#ifdef PERFMON_ENABLED\r
+ IBSPPmInit();\r
+#endif\r
break;\r
\r
case DLL_THREAD_ATTACH:\r
}\r
#endif\r
release_globals();\r
+#ifdef PERFMON_ENABLED\r
+ IBSPPmClose();\r
+#endif\r
break;\r
}\r
\r
{\r
IBSP_TRACE( IBSP_DBG_INIT, ("entry_count is 0 => cleaning up\n") );\r
ib_release();\r
+\r
+#ifdef PERFMON_ENABLED\r
+ IBSPPmReleaseSlot();\r
+#endif\r
}\r
\r
cl_spinlock_release( &g_ibsp.mutex );\r
\r
IBSP_EXIT( IBSP_DBG_INIT );\r
\r
+#ifdef PERFMON_ENABLED\r
+ /* Socket application register with perfmon */\r
+ IBSPPmGetSlot();\r
+#endif /* PERFMON_ENABLED */\r
+\r
return 0;\r
}\r
+\r
+\r
LIBRARY ibwsd\r
-EXPORTS \r
+EXPORTS\r
WSPStartupEx\r
+IBSPPmOpen\r
+IBSPPmCollectData\r
+IBSPPmClose\r
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 8.00\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ibspdll", "ibspdll.vcproj", "{414811DF-737C-43C0-BF6C-3D5B4EF416A9}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InstallSP", "..\InstallSP\InstallSP.vcproj", "{B3A2B7A0-1906-413E-A457-8AD2FC5E88BB}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test1", "..\unittest\test1\test1.vcproj", "{4FE83165-7E2D-4375-906B-0D2927DC4F8A}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ttcp", "..\unittest\ttcp\ttcp.vcproj", "{BB697350-4EF7-45AD-A25D-8411E21E516D}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test2", "..\unittest\test2\test2.vcproj", "{FAE22AE2-151A-4C26-A598-8440B3603DA7}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test3", "..\unittest\test3\test3.vcproj", "{8C3B680E-31D3-4A1C-AF19-51A17A50C439}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "contest", "..\unittest\contest\contest.vcproj", "{FE720CBD-A6BD-493C-9A65-F18B1ABE3DEC}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sockdupc", "..\..\..\..\..\Program Files\Microsoft SDK\Samples\netds\WinSock\Sockdup\sockdupc.vcproj", "{45F064C2-606E-494C-9961-A0BDF7BC7D78}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sockdups", "..\..\..\..\..\Program Files\Microsoft SDK\Samples\netds\WinSock\Sockdup\sockdups.vcproj", "{45F064C2-606E-494C-9961-A0BDF7BC7D78}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- EndProjectSection\r
-EndProject\r
-Global\r
- GlobalSection(SolutionConfiguration) = preSolution\r
- Debug = Debug\r
- Pre32_RETAIL = Pre32_RETAIL\r
- Release = Release\r
- EndGlobalSection\r
- GlobalSection(ProjectConfiguration) = postSolution\r
- {414811DF-737C-43C0-BF6C-3D5B4EF416A9}.Debug.ActiveCfg = Debug|Win32\r
- {414811DF-737C-43C0-BF6C-3D5B4EF416A9}.Debug.Build.0 = Debug|Win32\r
- {414811DF-737C-43C0-BF6C-3D5B4EF416A9}.Pre32_RETAIL.ActiveCfg = Release|Win32\r
- {414811DF-737C-43C0-BF6C-3D5B4EF416A9}.Pre32_RETAIL.Build.0 = Release|Win32\r
- {414811DF-737C-43C0-BF6C-3D5B4EF416A9}.Release.ActiveCfg = Release|Win32\r
- {414811DF-737C-43C0-BF6C-3D5B4EF416A9}.Release.Build.0 = Release|Win32\r
- {B3A2B7A0-1906-413E-A457-8AD2FC5E88BB}.Debug.ActiveCfg = Debug|Win32\r
- {B3A2B7A0-1906-413E-A457-8AD2FC5E88BB}.Debug.Build.0 = Debug|Win32\r
- {B3A2B7A0-1906-413E-A457-8AD2FC5E88BB}.Pre32_RETAIL.ActiveCfg = Release|Win32\r
- {B3A2B7A0-1906-413E-A457-8AD2FC5E88BB}.Pre32_RETAIL.Build.0 = Release|Win32\r
- {B3A2B7A0-1906-413E-A457-8AD2FC5E88BB}.Release.ActiveCfg = Release|Win32\r
- {B3A2B7A0-1906-413E-A457-8AD2FC5E88BB}.Release.Build.0 = Release|Win32\r
- {4FE83165-7E2D-4375-906B-0D2927DC4F8A}.Debug.ActiveCfg = Release|Win32\r
- {4FE83165-7E2D-4375-906B-0D2927DC4F8A}.Debug.Build.0 = Release|Win32\r
- {4FE83165-7E2D-4375-906B-0D2927DC4F8A}.Pre32_RETAIL.ActiveCfg = Release|Win32\r
- {4FE83165-7E2D-4375-906B-0D2927DC4F8A}.Pre32_RETAIL.Build.0 = Release|Win32\r
- {4FE83165-7E2D-4375-906B-0D2927DC4F8A}.Release.ActiveCfg = Release|Win32\r
- {4FE83165-7E2D-4375-906B-0D2927DC4F8A}.Release.Build.0 = Release|Win32\r
- {BB697350-4EF7-45AD-A25D-8411E21E516D}.Debug.ActiveCfg = Debug|Win32\r
- {BB697350-4EF7-45AD-A25D-8411E21E516D}.Debug.Build.0 = Debug|Win32\r
- {BB697350-4EF7-45AD-A25D-8411E21E516D}.Pre32_RETAIL.ActiveCfg = Release|Win32\r
- {BB697350-4EF7-45AD-A25D-8411E21E516D}.Pre32_RETAIL.Build.0 = Release|Win32\r
- {BB697350-4EF7-45AD-A25D-8411E21E516D}.Release.ActiveCfg = Release|Win32\r
- {BB697350-4EF7-45AD-A25D-8411E21E516D}.Release.Build.0 = Release|Win32\r
- {FAE22AE2-151A-4C26-A598-8440B3603DA7}.Debug.ActiveCfg = Debug|Win32\r
- {FAE22AE2-151A-4C26-A598-8440B3603DA7}.Debug.Build.0 = Debug|Win32\r
- {FAE22AE2-151A-4C26-A598-8440B3603DA7}.Pre32_RETAIL.ActiveCfg = Release|Win32\r
- {FAE22AE2-151A-4C26-A598-8440B3603DA7}.Pre32_RETAIL.Build.0 = Release|Win32\r
- {FAE22AE2-151A-4C26-A598-8440B3603DA7}.Release.ActiveCfg = Release|Win32\r
- {FAE22AE2-151A-4C26-A598-8440B3603DA7}.Release.Build.0 = Release|Win32\r
- {8C3B680E-31D3-4A1C-AF19-51A17A50C439}.Debug.ActiveCfg = Debug|Win32\r
- {8C3B680E-31D3-4A1C-AF19-51A17A50C439}.Debug.Build.0 = Debug|Win32\r
- {8C3B680E-31D3-4A1C-AF19-51A17A50C439}.Pre32_RETAIL.ActiveCfg = Release|Win32\r
- {8C3B680E-31D3-4A1C-AF19-51A17A50C439}.Pre32_RETAIL.Build.0 = Release|Win32\r
- {8C3B680E-31D3-4A1C-AF19-51A17A50C439}.Release.ActiveCfg = Release|Win32\r
- {8C3B680E-31D3-4A1C-AF19-51A17A50C439}.Release.Build.0 = Release|Win32\r
- {FE720CBD-A6BD-493C-9A65-F18B1ABE3DEC}.Debug.ActiveCfg = Debug|Win32\r
- {FE720CBD-A6BD-493C-9A65-F18B1ABE3DEC}.Debug.Build.0 = Debug|Win32\r
- {FE720CBD-A6BD-493C-9A65-F18B1ABE3DEC}.Pre32_RETAIL.ActiveCfg = Release|Win32\r
- {FE720CBD-A6BD-493C-9A65-F18B1ABE3DEC}.Pre32_RETAIL.Build.0 = Release|Win32\r
- {FE720CBD-A6BD-493C-9A65-F18B1ABE3DEC}.Release.ActiveCfg = Debug|Win32\r
- {FE720CBD-A6BD-493C-9A65-F18B1ABE3DEC}.Release.Build.0 = Debug|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Debug.ActiveCfg = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Debug.Build.0 = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Pre32_RETAIL.ActiveCfg = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Pre32_RETAIL.Build.0 = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Release.ActiveCfg = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Release.Build.0 = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Debug.ActiveCfg = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Debug.Build.0 = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Pre32_RETAIL.ActiveCfg = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Pre32_RETAIL.Build.0 = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Release.ActiveCfg = Pre32_RETAIL|Win32\r
- {45F064C2-606E-494C-9961-A0BDF7BC7D78}.Release.Build.0 = Pre32_RETAIL|Win32\r
- EndGlobalSection\r
- GlobalSection(ExtensibilityGlobals) = postSolution\r
- EndGlobalSection\r
- GlobalSection(ExtensibilityAddIns) = postSolution\r
- EndGlobalSection\r
-EndGlobal\r