* [PATCH iproute2-next v2 0/3] Improve batch and dump times by caching link lookups
@ 2019-02-14 0:22 David Ahern
2019-02-14 0:22 ` [PATCH iproute2-next v2 1/3] ll_map: Add function to remove link cache entry by index David Ahern
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: David Ahern @ 2019-02-14 0:22 UTC (permalink / raw)
To: stephen; +Cc: netdev, David Ahern
From: David Ahern <dsahern@gmail.com>
Many commands convert device names to an index using ll_name_to_index and
the reverse from an index to a name using ll_index_to_name.
At the moment both of the ll_ functions use the ioctl based helpers from
glibc which involves opening socket, calling ioctl and then closing the
socket on each device lookup. When using a batch file or dumping large
number of routes this means the same device lookups can be done repeatedly
adding unnecessary overhead to both operations.
This series adds a new function, ll_link_get, to send a netlink based
RTM_GETLINK. If successful, the result is cached in idx_head and name_head
so future lookups can re-use the entry. iproute2's ll_map functions are
updated to use ll_link_get over the glibc functions. The result is a
significant speed up in both batch and dumps with negligible overhead if
ip is invoked for single operations.
The first 2 patches add a means to drop an entry from the cache and updates
iplink_modify to use that new function to drop entries on device changes.
This forces the cache to re-learn device information if a batch file has a
mix of link set operations with other commands - such as adding a route.
v2
- changed the second patch to drop cache entry on any link changes
- added ll_link_get to index to name conversion improving dumps
David Ahern (3):
ll_map: Add function to remove link cache entry by index
ip link: Drop cache entry on any changes
Improve batch and dump times by caching link lookups
include/ll_map.h | 1 +
ip/iplink.c | 3 +++
lib/ll_map.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 69 insertions(+), 1 deletion(-)
--
2.11.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH iproute2-next v2 1/3] ll_map: Add function to remove link cache entry by index 2019-02-14 0:22 [PATCH iproute2-next v2 0/3] Improve batch and dump times by caching link lookups David Ahern @ 2019-02-14 0:22 ` David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 2/3] ip link: Drop cache entry on any changes David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 3/3] Improve batch and dump times by caching link lookups David Ahern 2 siblings, 0 replies; 4+ messages in thread From: David Ahern @ 2019-02-14 0:22 UTC (permalink / raw) To: stephen; +Cc: netdev, David Ahern From: David Ahern <dsahern@gmail.com> Add ll_drop_by_index to remove an entry from the link cache. Signed-off-by: David Ahern <dsahern@gmail.com> --- include/ll_map.h | 1 + lib/ll_map.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/include/ll_map.h b/include/ll_map.h index 511fe00b8567..4de1041e2746 100644 --- a/include/ll_map.h +++ b/include/ll_map.h @@ -9,6 +9,7 @@ unsigned ll_name_to_index(const char *name); const char *ll_index_to_name(unsigned idx); int ll_index_to_type(unsigned idx); int ll_index_to_flags(unsigned idx); +void ll_drop_by_index(unsigned index); unsigned namehash(const char *str); const char *ll_idx_n2a(unsigned int idx); diff --git a/lib/ll_map.c b/lib/ll_map.c index 1ab8ef0758ac..8e8a0b1e9c9d 100644 --- a/lib/ll_map.c +++ b/lib/ll_map.c @@ -210,6 +210,20 @@ unsigned ll_name_to_index(const char *name) return idx; } +void ll_drop_by_index(unsigned index) +{ + struct ll_cache *im; + + im = ll_get_by_index(index); + if (!im) + return; + + hlist_del(&im->idx_hash); + hlist_del(&im->name_hash); + + free(im); +} + void ll_init_map(struct rtnl_handle *rth) { static int initialized; -- 2.11.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH iproute2-next v2 2/3] ip link: Drop cache entry on any changes 2019-02-14 0:22 [PATCH iproute2-next v2 0/3] Improve batch and dump times by caching link lookups David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 1/3] ll_map: Add function to remove link cache entry by index David Ahern @ 2019-02-14 0:22 ` David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 3/3] Improve batch and dump times by caching link lookups David Ahern 2 siblings, 0 replies; 4+ messages in thread From: David Ahern @ 2019-02-14 0:22 UTC (permalink / raw) To: stephen; +Cc: netdev, David Ahern From: David Ahern <dsahern@gmail.com> Remove any entry from the link cache when the link is modified. Signed-off-by: David Ahern <dsahern@gmail.com> --- ip/iplink.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ip/iplink.c b/ip/iplink.c index b5519201fef7..393cefdc89df 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -1083,6 +1083,9 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) if (rtnl_talk(&rth, &req.n, NULL) < 0) return -2; + /* remove device from cache; next use can refresh with new data */ + ll_drop_by_index(req.i.ifi_index); + return 0; } -- 2.11.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH iproute2-next v2 3/3] Improve batch and dump times by caching link lookups 2019-02-14 0:22 [PATCH iproute2-next v2 0/3] Improve batch and dump times by caching link lookups David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 1/3] ll_map: Add function to remove link cache entry by index David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 2/3] ip link: Drop cache entry on any changes David Ahern @ 2019-02-14 0:22 ` David Ahern 2 siblings, 0 replies; 4+ messages in thread From: David Ahern @ 2019-02-14 0:22 UTC (permalink / raw) To: stephen; +Cc: netdev, David Ahern From: David Ahern <dsahern@gmail.com> ip route uses ll_name_to_index and ll_index_to_name to convert between device names and indices. At the moment both use for the ioctl based glibc functions if_nametoindex and if_indextoname and does not cache the result. When using a batch file or dumping large number of routes this means the same device lookups can be done repeatedly adding unnecessary overhead (socket + ioctl + close 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. Update ll_name_to_index and ll_index_to_name to use ll_link_get and only fallback to the glibc functions if it fails. With this change the time to install 720,022 routes with 2 ecmp nexthops where the nexthop device is given is reduced from 31.4 seconds to 19.2 seconds. A dump of those routes drops from 13.3 to 2.8 seconds. Signed-off-by: David Ahern <dsahern@gmail.com> --- lib/ll_map.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/ll_map.c b/lib/ll_map.c index 8e8a0b1e9c9d..2d7b65dcb8f7 100644 --- a/lib/ll_map.c +++ b/lib/ll_map.c @@ -152,6 +152,48 @@ static unsigned int ll_idx_a2n(const char *name) return idx; } +static int ll_link_get(const char *name, int index) +{ + 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, + .ifm.ifi_index = index, + }; + __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); + if (name) + 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; +} + const char *ll_index_to_name(unsigned int idx) { static char buf[IFNAMSIZ]; @@ -164,6 +206,12 @@ const char *ll_index_to_name(unsigned int idx) if (im) return im->name; + if (ll_link_get(NULL, idx) == idx) { + im = ll_get_by_index(idx); + if (im) + return im->name; + } + if (if_indextoname(idx, buf) == NULL) snprintf(buf, IFNAMSIZ, "if%u", idx); @@ -204,7 +252,9 @@ unsigned ll_name_to_index(const char *name) if (im) return im->index; - idx = if_nametoindex(name); + idx = ll_link_get(name, 0); + if (idx == 0) + idx = if_nametoindex(name); if (idx == 0) idx = ll_idx_a2n(name); return idx; -- 2.11.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-02-14 0:22 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-02-14 0:22 [PATCH iproute2-next v2 0/3] Improve batch and dump times by caching link lookups David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 1/3] ll_map: Add function to remove link cache entry by index David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 2/3] ip link: Drop cache entry on any changes David Ahern 2019-02-14 0:22 ` [PATCH iproute2-next v2 3/3] Improve batch and dump times by caching link lookups David Ahern
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.