summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Eitzenberger <holger@eitzenberger.org>2014-11-23 14:40:36 (GMT)
committerThomas Haller <thaller@redhat.com>2014-11-23 14:58:13 (GMT)
commit0020ba1212caad02841f72d680815e67d7180683 (patch)
treea38a4c76dfaffc7b17464735f5b2a2f445fe3f7f
parent15178401c264a348677db7a2d8cd041970a1ce72 (diff)
downloadlibnl-0020ba1212caad02841f72d680815e67d7180683.zip
libnl-0020ba1212caad02841f72d680815e67d7180683.tar.gz
libnl-0020ba1212caad02841f72d680815e67d7180683.tar.bz2
cache: avoid duplicate check on initial dump
The cache pickup does a check for duplicates for some time now. However, the pickup in nl_cache_refill() explicitely clears the cache, so the pickup doesn't need to actually do the dupe check, as uniqueness is already guaranteed be Netlink subsystem. And avoiding the dup check is beneficitial for performance reasons, as the current algorithm is O(n^2). http://lists.infradead.org/pipermail/libnl/2014-October/001680.html Fixes: 96bb7c9a4cdd10a2665c0f56120943e79e33c560 Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org> Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--include/netlink/cache.h2
-rw-r--r--lib/cache.c48
-rw-r--r--lib/fib_lookup/lookup.c2
3 files changed, 41 insertions, 11 deletions
diff --git a/include/netlink/cache.h b/include/netlink/cache.h
index a2b3dbb..71eaceb 100644
--- a/include/netlink/cache.h
+++ b/include/netlink/cache.h
@@ -78,6 +78,8 @@ extern int nl_cache_refill(struct nl_sock *,
struct nl_cache *);
extern int nl_cache_pickup(struct nl_sock *,
struct nl_cache *);
+extern int nl_cache_pickup_checkdup(struct nl_sock *,
+ struct nl_cache *);
extern int nl_cache_resync(struct nl_sock *,
struct nl_cache *,
change_func_t,
diff --git a/lib/cache.c b/lib/cache.c
index b4f9649..d68ee1f 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -708,7 +708,7 @@ static int __cache_pickup(struct nl_sock *sk, struct nl_cache *cache,
return err;
}
-static int pickup_cb(struct nl_object *c, struct nl_parser_param *p)
+static int pickup_checkdup_cb(struct nl_object *c, struct nl_parser_param *p)
{
struct nl_cache *cache = (struct nl_cache *)p->pp_arg;
struct nl_object *old;
@@ -727,6 +727,42 @@ static int pickup_cb(struct nl_object *c, struct nl_parser_param *p)
return nl_cache_add(cache, c);
}
+static int pickup_cb(struct nl_object *c, struct nl_parser_param *p)
+{
+ struct nl_cache *cache = p->pp_arg;
+
+ return nl_cache_add(cache, c);
+}
+
+static int __nl_cache_pickup(struct nl_sock *sk, struct nl_cache *cache,
+ int checkdup)
+{
+ struct nl_parser_param p;
+
+ p.pp_cb = checkdup ? pickup_checkdup_cb : pickup_cb;
+ p.pp_arg = cache;
+
+ if (sk->s_proto != cache->c_ops->co_protocol)
+ return -NLE_PROTO_MISMATCH;
+
+ return __cache_pickup(sk, cache, &p);
+}
+
+/**
+ * Pickup a netlink dump response and put it into a cache.
+ * @arg sk Netlink socket.
+ * @arg cache Cache to put items into.
+ *
+ * Waits for netlink messages to arrive, parses them and puts them into
+ * the specified cache.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int nl_cache_pickup_checkdup(struct nl_sock *sk, struct nl_cache *cache)
+{
+ return __nl_cache_pickup(sk, cache, 1);
+}
+
/**
* Pickup a netlink dump response and put it into a cache.
* @arg sk Netlink socket.
@@ -742,15 +778,7 @@ static int pickup_cb(struct nl_object *c, struct nl_parser_param *p)
*/
int nl_cache_pickup(struct nl_sock *sk, struct nl_cache *cache)
{
- struct nl_parser_param p = {
- .pp_cb = pickup_cb,
- .pp_arg = cache,
- };
-
- if (sk->s_proto != cache->c_ops->co_protocol)
- return -NLE_PROTO_MISMATCH;
-
- return __cache_pickup(sk, cache, &p);
+ return __nl_cache_pickup(sk, cache, 0);
}
static int cache_include(struct nl_cache *cache, struct nl_object *obj,
diff --git a/lib/fib_lookup/lookup.c b/lib/fib_lookup/lookup.c
index 3d07317..9b24635 100644
--- a/lib/fib_lookup/lookup.c
+++ b/lib/fib_lookup/lookup.c
@@ -270,7 +270,7 @@ int flnl_lookup(struct nl_sock *sk, struct flnl_request *req,
if (err < 0)
return err;
- return nl_cache_pickup(sk, cache);
+ return nl_cache_pickup_checkdup(sk, cache);
}
/** @} */