From owner-freebsd-current@FreeBSD.ORG Fri Aug 26 04:35:23 2005 Return-Path: X-Original-To: freebsd-current@freebsd.org Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 951EC16A41F for ; Fri, 26 Aug 2005 04:35:23 +0000 (GMT) (envelope-from rodrigc@crodrigues.org) Received: from sccrmhc11.comcast.net (sccrmhc11.comcast.net [63.240.76.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1E74743D45 for ; Fri, 26 Aug 2005 04:35:22 +0000 (GMT) (envelope-from rodrigc@crodrigues.org) Received: from c-66-30-115-133.hsd1.ma.comcast.net ([66.30.115.133]) by comcast.net (sccrmhc11) with ESMTP id <2005082604352001100li0vge>; Fri, 26 Aug 2005 04:35:20 +0000 Received: from c-66-30-115-133.hsd1.ma.comcast.net (localhost.127.in-addr.arpa [127.0.0.1]) by c-66-30-115-133.hsd1.ma.comcast.net (8.13.4/8.13.1) with ESMTP id j7Q4ZJjY003157 for ; Fri, 26 Aug 2005 00:35:19 -0400 (EDT) (envelope-from rodrigc@c-66-30-115-133.hsd1.ma.comcast.net) Received: (from rodrigc@localhost) by c-66-30-115-133.hsd1.ma.comcast.net (8.13.4/8.13.1/Submit) id j7Q4ZJFf003155 for freebsd-current@freebsd.org; Fri, 26 Aug 2005 00:35:19 -0400 (EDT) (envelope-from rodrigc) Date: Fri, 26 Aug 2005 00:35:18 -0400 From: Craig Rodrigues To: freebsd-current@freebsd.org Message-ID: <20050826043518.GA2090@crodrigues.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="CE+1k2dSO48ffgeK" Content-Disposition: inline User-Agent: Mutt/1.5.9i Subject: [PATCH] Eliminate witness warning in linux_ioctl.c X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Aug 2005 04:35:23 -0000 --CE+1k2dSO48ffgeK Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, If I run the following test: (1) Make sure that the linux_base-8 port is installed. (2) kldload linux.ko (3) Download and run the ifconfig program from Fedora: http://people.freebsd.org/~rodrigc/linux-test/ifconfig.bz2 I get this following WITNESS warning (not a LOR!!): Calling uiomove() with the following non-sleepable locks held: exclusive sleep mutex ifnet r = 0 (0xc096dd60) locked @ /usr/src/sys/modules/lin ux/../../compat/linux/linux_ioctl.c:2170 KDB: stack backtrace: kdb_backtrace(1,c17fe900,400,d165bc50,d165bbfc) at kdb_backtrace+0x29 witness_warn(5,0,c0856813,c064b97d,0) at witness_warn+0x18e uiomove(d165bc70,20,d165bc50,1,bfbfddb0) at uiomove+0x56 linux_ioctl_socket(c1b94000,d165bd04,c181e120,0,c1b94000) at linux_ioctl_socket+ 0x7dc linux_ioctl(c1b94000,d165bd04,3,3,246) at linux_ioctl+0x99 syscall(3b,3b,3b,b,bfbfe208) at syscall+0x22f Xint0x80_syscall() at Xint0x80_syscall+0x1f --- syscall (54, Linux ELF, linux_ioctl), eip = 0x283252a4, esp = 0xbfbfdd90, eb p = 0xbfbfe1e0 --- In order to eliminate this WITNESS warning, I modified linux_ifconf() to not use uiomove(). I based my changes on the logic used in ifconf() in net/if.c. Can someone provide feedback on this patch? Thanks. -- Craig Rodrigues rodrigc@crodrigues.org --CE+1k2dSO48ffgeK Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="linux_ioctl.c.diff.txt" Index: linux_ioctl.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_ioctl.c,v retrieving revision 1.128 diff -u -u -r1.128 linux_ioctl.c --- linux_ioctl.c 9 Aug 2005 10:19:41 -0000 1.128 +++ linux_ioctl.c 26 Aug 2005 04:33:38 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -2130,14 +2131,15 @@ struct l_ifreq ifr; struct ifnet *ifp; struct ifaddr *ifa; - struct iovec iov; - struct uio uio; - int error, ethno; + struct sbuf *sb; + int error, ethno, full = 0, valid_len, max_len; error = copyin(uifc, &ifc, sizeof(ifc)); if (error != 0) return (error); + max_len = MAXPHYS - 1; + /* handle the 'request buffer size' case */ if (ifc.ifc_buf == PTROUT(NULL)) { ifc.ifc_len = 0; @@ -2152,25 +2154,24 @@ return (error); } - /* much easier to use uiomove than keep track ourselves */ - iov.iov_base = PTRIN(ifc.ifc_buf); - iov.iov_len = ifc.ifc_len; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = 0; - uio.uio_resid = ifc.ifc_len; - uio.uio_segflg = UIO_USERSPACE; - uio.uio_rw = UIO_READ; - uio.uio_td = td; + if (ifc.ifc_len <= 0) + return (EINVAL); +again: /* Keep track of eth interfaces */ ethno = 0; + if (ifc.ifc_len <= max_len) { + max_len = ifc.ifc_len; + full = 1; + } + sb = sbuf_new(NULL, NULL, max_len + 1, SBUF_FIXEDLEN); + max_len = 0; + valid_len = 0; /* Return all AF_INET addresses of all interfaces */ IFNET_RLOCK(); /* could sleep XXX */ TAILQ_FOREACH(ifp, &ifnet, if_link) { - if (uio.uio_resid <= 0) - break; + int addrs = 0; bzero(&ifr, sizeof(ifr)); if (IFP_IS_ETH(ifp)) @@ -2183,26 +2184,39 @@ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { struct sockaddr *sa = ifa->ifa_addr; - if (uio.uio_resid <= 0) - break; - if (sa->sa_family == AF_INET) { ifr.ifr_addr.sa_family = LINUX_AF_INET; memcpy(ifr.ifr_addr.sa_data, sa->sa_data, sizeof(ifr.ifr_addr.sa_data)); - - error = uiomove(&ifr, sizeof(ifr), &uio); - if (error != 0) { - IFNET_RUNLOCK(); - return (error); - } + sbuf_bcat(sb, &ifr, sizeof(ifr)); + max_len += sizeof(ifr); + addrs++; } + + if (!sbuf_overflowed(sb)) + valid_len = sbuf_len(sb); + } + if (addrs == 0) { + bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); + sbuf_bcat(sb, &ifr, sizeof(ifr)); + max_len += sizeof(ifr); + + if (!sbuf_overflowed(sb)) + valid_len = sbuf_len(sb); } } IFNET_RUNLOCK(); - ifc.ifc_len -= uio.uio_resid; + if (valid_len != max_len && !full) { + sbuf_delete(sb); + goto again; + } + + ifc.ifc_len = valid_len; + sbuf_finish(sb); + memcpy(ifc.ifc_buf, sbuf_data(sb), ifc.ifc_len); error = copyout(&ifc, uifc, sizeof(ifc)); + sbuf_delete(sb); return (error); } --CE+1k2dSO48ffgeK--