From f78e316f25f8795e3e2b8d05ce2ecb908b62db9c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 22 Oct 2009 18:13:21 +0000 Subject: [PATCH] ip: Support IFLA_TXQLEN in ip link command MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Eric Dumazet a écrit : > We currently use an expensive ioctl() to get device txqueuelen, while > rtnetlink gave it to us for free. This patch speeds up ip link operation > when many devices are registered. > Here is a 2nd version od this patch, not displaying "qlen 0" useless info [PATCH iproute2] ip: Support IFLA_TXQLEN in ip link show command We currently use an expensive ioctl() to get device txqueuelen, while rtnetlink gave it to us for free. This patch speeds up ip link operation when many devices are registered. Signed-off-by: Eric Dumazet --- ip/ipaddress.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/ip/ipaddress.c b/ip/ipaddress.c index a1f78b9..85f05a2 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -130,26 +130,31 @@ static void print_operstate(FILE *f, __u8 state) fprintf(f, "state %s ", oper_states[state]); } -static void print_queuelen(FILE *f, const char *name) +static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1]) { - struct ifreq ifr; - int s; - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) - return; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, name); - if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { - fprintf(f, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno)); + int qlen; + + if (tb[IFLA_TXQLEN]) + qlen = *(int *)RTA_DATA(tb[IFLA_TXQLEN]); + else { + struct ifreq ifr; + int s = socket(AF_INET, SOCK_STREAM, 0); + + if (s < 0) + return; + + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, (char *)RTA_DATA(tb[IFLA_IFNAME])); + if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { + fprintf(f, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno)); + close(s); + return; + } close(s); - return; + qlen = ifr.ifr_qlen; } - close(s); - - if (ifr.ifr_qlen) - fprintf(f, "qlen %d", ifr.ifr_qlen); + if (qlen) + fprintf(f, "qlen %d", qlen); } static void print_linktype(FILE *fp, struct rtattr *tb) @@ -286,7 +291,7 @@ int print_linkinfo(const struct sockaddr_nl *who, print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE])); if (filter.showqueue) - print_queuelen(fp, (char*)RTA_DATA(tb[IFLA_IFNAME])); + print_queuelen(fp, tb); if (!filter.family || filter.family == AF_PACKET) { SPRINT_BUF(b1); -- 2.39.2