Originally posted by [b]Ai4rei[/b]
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=4737
Observed while doing some stress testing on eAthena, also previously reported in
Map-server Crash.
While having around 2000 online sessions, the host machine became low on memory and started to swap out and freezing up the char-server for a while. During that, the sessions that were online on map-server timed out and the map-server closed, while it attempted to save the characters, due to a rejected allocation of 256MB in realloc_writefifo.
Two issues with the WFIFO reallocation contribute to this problem. The major one of them is, that WFIFOSET calls realloc_writefifo with "current WFIFO data length"+"reserve", although realloc_writefifo is supposed to receive 'addition', which means, only the "reserve" itself. So as long the write buffer cannot be sent/flushed (since the other server is not reading data), every call to WFIFOSET causes the WFIFO size to grow to twice it's current length plus the reserve, which is 64k by default for server connections:
CODE
// always keep a WFIFO_SIZE reserve in the buffer
// For inter-server connections, let the reserve be 1/4th of the link size.
newreserve = s->wdata_size + ( s->flag.server ? FIFOSIZE_SERVERLINK / 4 : WFIFO_SIZE);
// readjust the buffer to the newly chosen size
realloc_writefifo(fd, newreserve);
The WFIFOHEAD macro, which also uses realloc_writefifo, does this properly.
The second issue only rounds up the first failure, so that the allocations take place in whole mega bytes, because the 'newsize' in realloc_writefifo is being increased by adding itself, rather than WFIFO_SIZE as specified by the grow rule in the comment:
CODE
if( session[fd]->wdata_size + addition > session[fd]->max_wdata )
{ // grow rule; grow in multiples of WFIFO_SIZE
newsize = WFIFO_SIZE;
while( session[fd]->wdata_size + addition > newsize ) newsize += newsize;
}
Currently the map-server WFIFO is about 1-16MB with 2000 players (moderate processing lag). With this issue fixed the WFIFO is kept around few kilobytes up to 3MB, though the WFIFO is reallocated more often when growing (16k steps), which can be changed by altering the WFIFO_SIZE define. Related
r11503,
r11571,
r11886 and
r12232.
This post has been edited by Ai4rei: Jan 31 2011, 06:38 AM