diff options
author | Cong Wang <xiyou.wangcong@gmail.com> | 2014-11-20 12:26:01 -0800 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-11-24 10:49:34 +0100 |
commit | 9c066b9271493ce3efff0b9d7b6e424990bba3f2 (patch) | |
tree | 5bf2926a29ebcfdcee192135db8753e9d026429c /lib/idiag | |
parent | 0020ba1212caad02841f72d680815e67d7180683 (diff) | |
download | libnl-9c066b9271493ce3efff0b9d7b6e424990bba3f2.tar.gz |
idiag: provide a hash function for idiag objects
Without ->oo_keygen, libnl will use linear search
for cache objects. This is extremely slow for idiag
when we have a lot of TCP connections. Provide a
hash function for idiag so that libnl will be able
to lookup a hashtable.
http://lists.infradead.org/pipermail/libnl/2014-November/001715.html
Cc: Thomas Graf <tgraf@suug.ch>
Cc: Thomas Haller <thaller@redhat.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/idiag')
-rw-r--r-- | lib/idiag/idiag_msg_obj.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/idiag/idiag_msg_obj.c b/lib/idiag/idiag_msg_obj.c index 19e6c5be..92a98e91 100644 --- a/lib/idiag/idiag_msg_obj.c +++ b/lib/idiag/idiag_msg_obj.c @@ -10,6 +10,7 @@ */ #include <netlink-private/netlink.h> +#include <netlink/hashtable.h> #include <netlink/idiag/msg.h> #include <netlink/idiag/meminfo.h> #include <netlink/idiag/vegasinfo.h> @@ -710,6 +711,32 @@ errout_nomem: goto errout; } +static void idiagnl_keygen(struct nl_object *obj, uint32_t *hashkey, + uint32_t table_sz) +{ + struct idiagnl_msg *msg = (struct idiagnl_msg *)obj; + unsigned int key_sz; + struct idiagnl_hash_key { + uint8_t family; + uint8_t state; + uint16_t sport; + uint16_t dport; + } __attribute__((packed)) key; + + key_sz = sizeof(key); + key.family = msg->idiag_family; + key.state = msg->idiag_state; + key.sport = msg->idiag_sport; + key.dport = msg->idiag_dport; + + *hashkey = nl_hash(&key, key_sz, 0) % table_sz; + + NL_DBG(5, "idiagnl %p key (fam %d state %d sport %d dport %d) keysz %d, hash 0x%x\n", + msg, key.family, key.state, key.sport, key.dport, key_sz, *hashkey); + + return; +} + /** @cond SKIP */ struct nl_object_ops idiagnl_msg_obj_ops = { .oo_name = "idiag/idiag_msg", @@ -721,6 +748,7 @@ struct nl_object_ops idiagnl_msg_obj_ops = { [NL_DUMP_DETAILS] = idiag_msg_dump_details, [NL_DUMP_STATS] = idiag_msg_dump_stats, }, + .oo_keygen = idiagnl_keygen, .oo_attrs2str = idiagnl_attrs2str, .oo_id_attrs = (IDIAG_ATTR_INFO) }; |