Bug 315641

Summary: TCP socket stat slows down dramatically when many TCP connections are open.
Product: [Unmaintained] ksysguard Reporter: whitehat.cog
Component: ksysguarddAssignee: KSysGuard Developers <ksysguard-bugs>
Status: RESOLVED WORKSFORME    
Severity: normal    
Priority: NOR    
Version First Reported In: 4.8   
Target Milestone: ---   
Platform: Ubuntu   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description whitehat.cog 2013-02-22 17:57:06 UTC
I have noticed when a system has over 3,000 open TCP connections, while the underlying Linux OS can handle it and the app managing the 3,000+ open TCP connections can handle it, ksysguardd ramps up to 100% CPU utilization at this point.  I tried with up to 12,000 open TCP sockets and while everything else was fine, ksysguardd slowed to a crawl while running at 100% CPU utilization.  I found the source of the problem in /ksysguard/ksysguardd/netstat.c.  Specifically the get_num_sockets() function on line 166 loops through the file /proc/net/tcp and counts up the lines, which can become quite large when many TCP sockets are open.  What I did to fix this was to tap into the file /proc/net/sockstat and just grab the one line I need.  I noticed that the /proc/net/tcp results and /proc/net/sockstat listing when combining the inuse and tw stats don't always match up, but combined (inuse and tw) they usually match up to manual counting and is a whole heck of a lot faster.

Here is the code I added / changed in order to facilitate this dramatic performance boost:

On line 176 after the get_num_sockets() fuction:
int get_num_sockets_sockstat(FILE *netstat, const char *stat_type)
{
	char line[1024];
	int line_count= 0;
	int inuse, orphan, tw, alloc, mem;
	inuse= orphan= tw= alloc= mem= 0;
	char *read_result= NULL;

	read_result= fgets(line, 1024, netstat); /* Read and throw away sockets total */
	read_result= fgets(line, 1024, netstat); /* Read TCP stats */
	if (strcmp("tcp", stat_type) == 0) { /* Get TCP stats */
		if (read_result != NULL) {
			sscanf (line, "TCP: inuse %i orphan %i tw %i alloc %i mem %i",
				&inuse, &orphan, &tw, &alloc, &mem);
			line_count= inuse + tw;
		}
	} else if (strcmp("udp", stat_type) == 0) { /* Get UDP stat */
		read_result= fgets(line, 1024, netstat); /* Read UDP stat */
		if (read_result != NULL) {
			sscanf (line, "UDP: inuse %i mem %i",
				&inuse, &mem);
			line_count= inuse + tw;
		}
	} else if (strcmp("raw", stat_type) == 0) { /* Get RAW stat */
		read_result= fgets(line, 1024, netstat); /* Read and throw away UDP stat */
		read_result= fgets(line, 1024, netstat); /* Read and throw away UDP Lite stat */
		read_result= fgets(line, 1024, netstat); /* Read RAW stat */
		if (read_result != NULL) {
			sscanf (line, "RAW: inuse %i",
				&inuse);
			line_count= inuse;
		}
	}

	return line_count;
} /* End get_num_sockets_sockstat */


And for what is now my line 274 function updateNetStat() I changed the file opened for TCP, UDP, and RAW to open the /proc/net/sockstat file instead.

Reproducible: Always

Steps to Reproduce:
1. Open ksysguard and monitor open TCP sockets.
2. Run a program that can potentially have lots of open TCP sockets such as Apache.
3. Run script to open and hold open TCP connections as this is the lazy way to get a whole lot of connections to be open at once.
Actual Results:  
ksysguardd reached maximum CPU utilization around 3,000 open TCP connections and slowed to a crawl as the connection count went up to 12,000 open TCP connections.

The above patch I made seems to have fixed this problem.  Of course with anything open source you are free to poke at it and let me know what you think.

Expected Results:  
No extra CPU load as more TCP connections are open as ksysguardd is supposed to monitor activity, not grind through intensive analysis every time it is polled.

This was run on Ubuntu 12.04 LTS 64-bit.  The source was downloaded from the included package manager.
Comment 1 Andrew Crouthamel 2018-11-10 03:17:09 UTC
Dear Bug Submitter,

This bug has been stagnant for a long time. Could you help us out and re-test if the bug is valid in the latest version? I am setting the status to NEEDSINFO pending your response, please change the Status back to REPORTED when you respond.

Thank you for helping us make KDE software even better for everyone!
Comment 2 Andrew Crouthamel 2018-11-20 04:03:58 UTC
Dear Bug Submitter,

This is a reminder that this bug has been stagnant for a long time. Could you help us out and re-test if the bug is valid in the latest version? This bug will be moved back to REPORTED Status for manual review later, which may take a while. If you are able to, please lend us a hand.

Thank you for helping us make KDE software even better for everyone!
Comment 3 Justin Zobel 2023-01-01 04:20:07 UTC
Thank you for reporting this issue in KDE software. As it has been a while since this issue was reported, can we please ask you to see if you can reproduce the issue with a recent software version?

If you can reproduce the issue, please change the status to "REPORTED" when replying. Thank you!
Comment 4 Bug Janitor Service 2023-01-16 05:13:35 UTC
Dear Bug Submitter,

This bug has been in NEEDSINFO status with no change for at least
15 days. Please provide the requested information as soon as
possible and set the bug status as REPORTED. Due to regular bug
tracker maintenance, if the bug is still in NEEDSINFO status with
no change in 30 days the bug will be closed as RESOLVED > WORKSFORME
due to lack of needed information.

For more information about our bug triaging procedures please read the
wiki located here:
https://community.kde.org/Guidelines_and_HOWTOs/Bug_triaging

If you have already provided the requested information, please
mark the bug as REPORTED so that the KDE team knows that the bug is
ready to be confirmed.

Thank you for helping us make KDE software even better for everyone!
Comment 5 Bug Janitor Service 2023-01-31 05:05:47 UTC
This bug has been in NEEDSINFO status with no change for at least
30 days. The bug is now closed as RESOLVED > WORKSFORME
due to lack of needed information.

For more information about our bug triaging procedures please read the
wiki located here:
https://community.kde.org/Guidelines_and_HOWTOs/Bug_triaging

Thank you for helping us make KDE software even better for everyone!