All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Ahern <dsahern@kernel.org>
To: stephen@networkplumber.org
Cc: netdev@vger.kernel.org, David Ahern <dsahern@gmail.com>
Subject: [PATCH iproute2-next] Improve batch times by caching link lookups
Date: Mon,  7 Jan 2019 12:41:30 -0800	[thread overview]
Message-ID: <20190107204130.32144-1-dsahern@kernel.org> (raw)

From: David Ahern <dsahern@gmail.com>

ip route uses ll_name_to_index to convert the user given device name to an
index. At the moment ll_name_to_index uses if_nametoindex which is ioctl
based and does not cache the result. When using a batch file this means
the same device lookups can be done repeatedly adding unnecessary overhead
(socket + ioctl call for each device lookup).

Add a new function, ll_link_get, to send a netlink based RTM_GETLINK. If
successful, cache the result in idx_head and name_head so future lookups
can re-use the entry.

With this change the time to install routes via a batch file is reduced
from 30.7 seconds to 17.6 seconds (720,022 routes with 2 ecmp nexthops
where the nexthop device is given).

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 lib/ll_map.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/lib/ll_map.c b/lib/ll_map.c
index 1ab8ef0758ac..4fbd9fa70dd7 100644
--- a/lib/ll_map.c
+++ b/lib/ll_map.c
@@ -192,6 +192,46 @@ int ll_index_to_flags(unsigned idx)
 	return im ? im->flags : -1;
 }
 
+static int ll_link_get(const char *name)
+{
+	struct {
+		struct nlmsghdr		n;
+		struct ifinfomsg	ifm;
+		char			buf[1024];
+	} req = {
+		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+		.n.nlmsg_flags = NLM_F_REQUEST,
+		.n.nlmsg_type = RTM_GETLINK,
+	};
+	__u32 filt_mask = RTEXT_FILTER_VF | RTEXT_FILTER_SKIP_STATS;
+	struct rtnl_handle rth = {};
+	struct nlmsghdr *answer;
+	int rc = 0;
+
+	if (rtnl_open(&rth, 0) < 0)
+		return 0;
+
+	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
+	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name,
+		  strlen(name) + 1);
+
+	if (rtnl_talk(&rth, &req.n, &answer) < 0)
+		goto out;
+
+	/* add entry to cache */
+	rc  = ll_remember_index(answer, NULL);
+	if (!rc) {
+		struct ifinfomsg *ifm = NLMSG_DATA(answer);
+
+		rc = ifm->ifi_index;
+	}
+
+	free(answer);
+out:
+	rtnl_close(&rth);
+	return rc;
+}
+
 unsigned ll_name_to_index(const char *name)
 {
 	const struct ll_cache *im;
@@ -204,7 +244,9 @@ unsigned ll_name_to_index(const char *name)
 	if (im)
 		return im->index;
 
-	idx = if_nametoindex(name);
+	idx = ll_link_get(name);
+	if (idx == 0)
+		idx = if_nametoindex(name);
 	if (idx == 0)
 		idx = ll_idx_a2n(name);
 	return idx;
-- 
2.11.0

             reply	other threads:[~2019-01-07 20:43 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-07 20:41 David Ahern [this message]
2019-01-07 20:57 ` [PATCH iproute2-next] Improve batch times by caching link lookups Eric Dumazet
2019-01-07 20:58   ` David Ahern
2019-01-07 21:06     ` Eric Dumazet
2019-01-07 21:16       ` David Ahern
2019-01-07 21:31 ` Stephen Hemminger
2019-01-07 21:52   ` David Ahern

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190107204130.32144-1-dsahern@kernel.org \
    --to=dsahern@kernel.org \
    --cc=dsahern@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.