From owner-freebsd-stable@FreeBSD.ORG Sun Jun 6 01:48:02 2010 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2381A106567A for ; Sun, 6 Jun 2010 01:48:02 +0000 (UTC) (envelope-from ncrogers@gmail.com) Received: from mail-iw0-f182.google.com (mail-iw0-f182.google.com [209.85.214.182]) by mx1.freebsd.org (Postfix) with ESMTP id DB34B8FC0C for ; Sun, 6 Jun 2010 01:48:01 +0000 (UTC) Received: by iwn5 with SMTP id 5so2850232iwn.13 for ; Sat, 05 Jun 2010 18:48:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:content-type; bh=DaHg0ZBS/jkYp0k5h3afns5I5xh0C27nv9KU9h527Jw=; b=hRRvF42FWoKejMaohrb9R5yUNVUR2Kc6JROTeo89i0Nt6wn3BmZa3ZNNbLu0sQgYq5 cx8+Y5krcrYmYqgJhhubnInbjUyZDmf2NDXI1C6TdLraYkM1fL2By+3dHml7pnhk/9ps fM+l4UfkXArNTch9rTPo9a+7OXkq8x6Lc6Y0I= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=OsH99c70eTgT/ugsnB1eJJ5BRme/qXy65Cog56Lk5CTpG3O2YIGB/lSYgziw7ntGto VWdToINyOpqHfpPhTnApggImMx9kJSAFCJN12t3zhGyLUG8ChevUrihg44hIXL+8i3hf xlkNVU4k3be/FFpHwrXVMunc5yg0+ZHz8Pk2c= MIME-Version: 1.0 Received: by 10.231.45.144 with SMTP id e16mr2691071ibf.130.1275788881100; Sat, 05 Jun 2010 18:48:01 -0700 (PDT) Received: by 10.231.190.131 with HTTP; Sat, 5 Jun 2010 18:48:01 -0700 (PDT) In-Reply-To: References: Date: Sat, 5 Jun 2010 21:48:01 -0400 Message-ID: From: Nick Rogers To: FreeBSD STABLE Content-Type: text/plain; charset=ISO-8859-1 X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Re: arp -na performance w/ many permanent entries X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 06 Jun 2010 01:48:02 -0000 On Mon, May 31, 2010 at 10:54 PM, Nick Rogers wrote: > > [root@ ~]# time arp -na > /dev/null > > real 0m12.761s > user 0m2.959s > sys 0m9.753s > [root@ ~]# > > > Notice that "arp -na" takes about 13s to execute even though there is no > other load. This can get a lot worse by a few orders of magnitude on a > loaded machine in a production environment, and seems to scale up linearly > when more aliases are added to the interface (permanent ARP entries > created). > > Is this a reasonable problem that can be fixed/improved, or am I stuck with > the slow arp -na output? Any help or comments is greatly appreciated. > I tried the same scenario on 8.1-BETA1 and it still takes a very long time for arp(8) to complete. I was able to isolate the performance bottleneck to a small piece of the arp(8) code. It seems that looking up the interface for an ARP entry is a very heavy operation when that entry corresponds to an alias assigned to the interface. Permanent ARP entries that do not correspond with an interface alias do not seem to cause arp(8) to puke on the interface lookup. The following commands and code diff illustrates how arp(8) can be modified to run a lot faster in this scenario, but obviously the associated interface is no longer printed for each entry. [root@ /usr/src/usr.sbin/arp]# uname -a FreeBSD .localdomain 8.1-BETA1 FreeBSD 8.1-BETA1 #0: Thu May 27 15:03:30 UTC 2010 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64 [root@ /usr/src/usr.sbin/arp]# time /usr/sbin/arp -na | wc -l 4100 real 0m14.903s user 0m3.133s sys 0m11.519s [root@ /usr/src/usr.sbin/arp]# pwd /usr/src/usr.sbin/arp [root@ /usr/src/usr.sbin/arp]# !diff diff -ruN arp.c.orig arp.c --- arp.c.orig 2010-06-05 18:25:24.000000000 +0000 +++ arp.c 2010-06-05 18:28:19.000000000 +0000 @@ -562,7 +562,7 @@ const char *host; struct hostent *hp; struct iso88025_sockaddr_dl_data *trld; - char ifname[IF_NAMESIZE]; + //char ifname[IF_NAMESIZE]; int seg; if (nflag == 0) @@ -591,8 +591,8 @@ } } else printf("(incomplete)"); - if (if_indextoname(sdl->sdl_index, ifname) != NULL) - printf(" on %s", ifname); + //if (if_indextoname(sdl->sdl_index, ifname) != NULL) + //printf(" on %s", ifname); if (rtm->rtm_rmx.rmx_expire == 0) printf(" permanent"); else { [root@ /usr/src/usr.sbin/arp]# make clean && make rm -f arp arp.o arp.4.gz arp.8.gz arp.4.cat.gz arp.8.cat.gz Warning: Object directory not changed from original /usr/src/usr.sbin/arp cc -O2 -pipe -std=gnu99 -fstack-protector -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wno-uninitialized -Wno-pointer-sign -c arp.c cc -O2 -pipe -std=gnu99 -fstack-protector -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wno-uninitialized -Wno-pointer-sign -o arp arp.o gzip -cn arp.4 > arp.4.gz gzip -cn arp.8 > arp.8.gz [root@ /usr/src/usr.sbin/arp]# time ./arp -na | wc -l 4099 real 0m0.036s user 0m0.015s sys 0m0.021s [root@ /usr/src/usr.sbin/arp]# Notice that 0.036s without the interface lookup is a heck of a lot faster than 14.903s when doing the interface lookup. Is there something that can be done to speedup the call to if_indextoname(), or would it be worthwhile for me to submit a patch that adds the ability to skip the interface lookup as an arp(8) option?