<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.2873" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>Hi 
Fab,</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>In the previous 
couple of days I was doing a study on a small program. This program 
was using WSD and was doing many connects to the remote side. (the source 
of it is in the end of this mail).</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>It seems that this 
program was running, but looking at the task manager showed that the memory, 
threads and handles were going up.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>I have made some 
investigation of the problem found there and here are my 
results:</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>1) Once the program 
was connecting, the number of WSD sockets that were opened and not closed was 
increasing all the time. This seems like a reason for the leak. When I have 
stopped the main thread from connecting, it seems that the sockets have been 
closed. This is some mitigation, but If there is something that we can do about 
it than we should probably do.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>2) It seems that the 
mechanism that allocates a CQ and a thread for it every time that we reach the 
maximum size is broken. That is there might be empty CQ's while new ones will 
still be opened. This problem will probably be smaller when resize CQ will be 
implemented.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>3) The next problem 
that I saw was that the handles don't come down even when I stop from time to 
time. After some debugging I understood that the main reason is that this 
handles represent allocations. When they are freed they return to a pool that 
can only increase in size. This is probably fine.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>4) The last issue 
was memory demand that was constantly increasing. using gflags and umdh.exe I 
was not able to find any real leak (the program was still leaking about 50 MB a 
minute). After some investigation, I came to conclusion that the memory that was 
registered in the cache and later we have used MmSecureVirtualMemory on it was 
leaking. (I'll probably have to make some more investigations to fully 
understand this, but this is what I currently see). When I have removed 
this call from the driver it seems that the problem was over (As the 
program got stacked very soon it is hard to be sure).</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>So, My 
questions are: 1) have you seen this before. 2) One of the WSD goals is to 
run everything that Ethernet can. It seems that this simple program will run 
forever on Ethernet, but only a few seconds on WSD. Can we do anything to fix 
it?</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006>Thanks</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006>Tzachi</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>Code of the 
program:</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>int 
client_main(<BR> IN struct VL_random_t *rand_t)<BR>{<BR> struct 
sockaddr_in  serv_addr;<BR> struct 
in_addr   remote_addr;<BR> SOCKET    *socket_array 
= NULL;<BR> char    *buf = 
NULL;<BR> int    num_sends_per_port = 
(config.num_connections / config.num_outs_connections) * 
config.num_outs_connections;<BR> int    i;<BR> int    j;<BR> int    result 
= -1;<BR> int    rc;<BR> int 
    count = 0;</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006> <BR> socket_array = 
malloc(config.num_outs_connections * config.num_ports * 
sizeof(SOCKET));<BR> CHECK_NOT_EQUAL("malloc", socket_array, NULL, goto 
cleanup);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006> memset(socket_array, 0, 
config.num_outs_connections * config.num_ports * 
sizeof(SOCKET));</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006> buf = 
malloc(config.num_outs_connections * config.num_ports * 
config.message_size);<BR> CHECK_NOT_EQUAL("malloc", buf, NULL, goto 
cleanup);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006> remote_addr.S_un.S_addr = 
inet_addr(config.ip);<BR> CHECK_NOT_EQUAL("inet_addr", 
remote_addr.S_un.S_addr, INADDR_NONE, goto cleanup);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006> serv_addr.sin_addr = 
remote_addr;      <BR> serv_addr.sin_family = 
AF_INET;<BR> serv_addr.sin_port = 
htons((u_short)config.portnum);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006> for (i = 0; i 
< config.num_outs_connections * config.num_ports; 
++i)<BR>  set_buffer_data(buf +  i * config.message_size, 
config.message_size, i % config.num_ports);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006> for (j = 0; j 
< num_sends_per_port; j += config.num_outs_connections) {<BR>  for 
(i = 0; i < config.num_outs_connections * config.num_ports; ++i) 
{<BR>   if (socket_array[i]) {<BR>    rc = 
closesocket(socket_array[i]);<BR>    CHECK_VALUE("closesocket", 
rc, 0, goto cleanup);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006>    socket_array[i] = 
0;<BR>   }</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006>   socket_array[i] = socket(AF_INET, 
SOCK_STREAM, 0);<BR>   CHECK_NOT_EQUAL("socket", socket_array[i], 
INVALID_SOCKET, goto cleanup);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=806042119-06072006>   serv_addr.sin_port = 
htons((u_short)config.portnum + (i % config.num_ports));</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>   rc 
= connect(socket_array[i], (struct sockaddr*)&serv_addr, 
sizeof(serv_addr));<BR>   CHECK_NOT_EQUAL("connect", rc, 
SOCKET_ERROR, printf("i %d j %d gle=%d\n", i, j, GetLastError()); goto 
cleanup);<BR>   OutputDebugString("Connect 
finished\n");<BR>   printf("Connect 
finished\n");<BR>   count ++;<BR>   if (count % 
1000 == 0) {<BR>    printf("sleeping 
\n");<BR>    Sleep(20000);<BR>   }</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006>   rc 
= do_regular_send(socket_array[i], buf + i * config.message_size, 
config.message_size, 0);<BR>   CHECK_VALUE("do_regular_send", rc, 
0, goto cleanup);<BR>  }<BR> }<BR> <BR> result = 
0;<BR>cleanup:<BR> <BR> if (socket_array) {<BR>  for (i = 0; 
i < config.num_outs_connections * config.num_ports; ++i) 
{<BR>   if (socket_array[i]) {<BR>    rc = 
closesocket(socket_array[i]);<BR>    CHECK_NOT_EQUAL("closesocket", 
rc, SOCKET_ERROR, result = -1; 
break);<BR>   }<BR>  }<BR>  free(socket_array);<BR> }</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006> if 
(buf)<BR>  free(buf);</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=806042119-06072006> return 
result;<BR>}</SPAN></FONT></DIV></BODY></HTML>