<!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>