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