From nobody@FreeBSD.org  Thu Dec  3 09:14:34 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 4253E106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  3 Dec 2009 09:14:34 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 321638FC1A
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  3 Dec 2009 09:14:34 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id nB39EXxe022521
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 3 Dec 2009 09:14:33 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id nB39EXqf022520;
	Thu, 3 Dec 2009 09:14:33 GMT
	(envelope-from nobody)
Message-Id: <200912030914.nB39EXqf022520@www.freebsd.org>
Date: Thu, 3 Dec 2009 09:14:33 GMT
From: liujb <liujb@arraynetworks.com.cn>
To: freebsd-gnats-submit@FreeBSD.org
Subject: rpc may causes high cpu usage
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         141130
>Category:       amd64
>Synopsis:       rpc may causes high cpu usage
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    jhb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 03 09:20:04 UTC 2009
>Closed-Date:    Mon Oct 11 17:59:22 UTC 2010
>Last-Modified:  Mon Oct 11 17:59:22 UTC 2010
>Originator:     liujb
>Release:        FreeBSD7.0
>Organization:
array networks
>Environment:
FreeBSD 7.0-RELEASE 
>Description:
In svc_getreqset function, high-number fd will not be handled.
Data is still in receiving buffer, so rpc lib will be called 
frequently, which leads high cpu usage.  

It's because fd_mask is unsinged long, which is 64-bits in amd64,
but ffs only handles 32bit int. The high fd will be ingored, 
and jump out of the second for loop.

Please read my comments in the following source code.

void
svc_getreqset(readfds)
        fd_set *readfds;
{
        int bit, fd;
        fd_mask mask, *maskp;
        int sock;

        assert(readfds != NULL);

        maskp = readfds->fds_bits;
        for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) {
            for (mask = *maskp++; (bit = ffs(mask)) != 0;    
                                         -->should be ffsl
                mask ^= (1 << (bit - 1))) {                  
                         -->1 should be (long)1
                /* sock has input waiting */
                fd = sock + bit - 1;
                svc_getreq_common(fd);
            }
        }
}

>How-To-Repeat:
Open a rpc connection with a high number file description.
>Fix:
The fix should be take care of the long type of fd_mask in i386 and amd64, 
also should pay attention to other places using ffs.

>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: amd64/141130: commit references a PR
Date: Thu,  3 Dec 2009 15:14:45 +0000 (UTC)

 Author: jhb
 Date: Thu Dec  3 15:14:30 2009
 New Revision: 200061
 URL: http://svn.freebsd.org/changeset/base/200061
 
 Log:
   The fd_mask type is an unsigned long, not an int, so treat the mask as a
   long instead of an int when examining the results of select() to look for
   RPC requests.  Previously this routine would ignore RPC requests to sockets
   whose file descriptor mod 64 was greater than 31 on a 64-bit platform.
   
   PR:		amd64/141130
   Submitted by:	liujb of array networks
   MFC after:	3 days
 
 Modified:
   head/lib/libc/rpc/svc.c
 
 Modified: head/lib/libc/rpc/svc.c
 ==============================================================================
 --- head/lib/libc/rpc/svc.c	Thu Dec  3 14:59:42 2009	(r200060)
 +++ head/lib/libc/rpc/svc.c	Thu Dec  3 15:14:30 2009	(r200061)
 @@ -627,8 +627,8 @@ svc_getreqset(readfds)
  
  	maskp = readfds->fds_bits;
  	for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) {
 -	    for (mask = *maskp++; (bit = ffs(mask)) != 0;
 -		mask ^= (1 << (bit - 1))) {
 +	    for (mask = *maskp++; (bit = ffsl(mask)) != 0;
 +		mask ^= (1ul << (bit - 1))) {
  		/* sock has input waiting */
  		fd = sock + bit - 1;
  		svc_getreq_common(fd);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: jhb 
State-Changed-When: Thu Dec 3 16:26:53 UTC 2009 
State-Changed-Why:  
Take this. 


Responsible-Changed-From-To: freebsd-amd64->jhb 
Responsible-Changed-By: jhb 
Responsible-Changed-When: Thu Dec 3 16:26:53 UTC 2009 
Responsible-Changed-Why:  
Take this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141130 
State-Changed-From-To: patched->closed 
State-Changed-By: jhb 
State-Changed-When: Mon Oct 11 17:58:15 UTC 2010 
State-Changed-Why:  
This was merged to 7 and 8 a while ago, just forgot to close the PR until 
now. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141130 
>Unformatted:
