Re: [PATCH net-next 2/3] netlink: Convert netlink_lookup() to use RCU protected hash table

From: Nikolay Aleksandrov
Date: Fri Aug 01 2014 - 10:58:11 EST


On 08/01/2014 01:58 PM, Thomas Graf wrote:
> Heavy Netlink users such as Open vSwitch spend a considerable amount of
> time in netlink_lookup() due to the read-lock on nl_table_lock. Use of
> RCU relieves the lock contention.
>
> Makes use of the new resizable hash table to avoid locking on the
> lookup.
>
> The hash table will grow if entries exceeds 75% of table size up to a
> total table size of 64K. It will automatically shrink if usage falls
> below 50%.
>
> Also splits nl_table_lock into a separate spinlock to protect hash table
> mutations. This avoids a possible deadlock when the hash table growing
> waits on RCU readers to complete via synchronize_rcu() while readers
> holding RCU read lock are waiting on the nl_table_lock() to be released
> to lock the table for broadcasting.
>
> Before:
> 9.16% kpktgend_0 [openvswitch] [k] masked_flow_lookup
> 6.42% kpktgend_0 [pktgen] [k] mod_cur_headers
> 6.26% kpktgend_0 [pktgen] [k] pktgen_thread_worker
> 6.23% kpktgend_0 [kernel.kallsyms] [k] memset
> 4.79% kpktgend_0 [kernel.kallsyms] [k] netlink_lookup
> 4.37% kpktgend_0 [kernel.kallsyms] [k] memcpy
> 3.60% kpktgend_0 [openvswitch] [k] ovs_flow_extract
> 2.69% kpktgend_0 [kernel.kallsyms] [k] jhash2
>
> After:
> 15.26% kpktgend_0 [openvswitch] [k] masked_flow_lookup
> 8.12% kpktgend_0 [pktgen] [k] pktgen_thread_worker
> 7.92% kpktgend_0 [pktgen] [k] mod_cur_headers
> 5.11% kpktgend_0 [kernel.kallsyms] [k] memset
> 4.11% kpktgend_0 [openvswitch] [k] ovs_flow_extract
> 4.06% kpktgend_0 [kernel.kallsyms] [k] _raw_spin_lock
> 3.90% kpktgend_0 [kernel.kallsyms] [k] jhash2
> [...]
> 0.67% kpktgend_0 [kernel.kallsyms] [k] netlink_lookup
>
> Signed-off-by: Thomas Graf <tgraf@xxxxxxx>
> ---

Hmm, in both the rhashtable_insert() and rhashtable_remove() calls in the
netlink code you're using GFP_ATOMIC flags but if rhashtable_expand/shring gets
called even though the allocation will be with GFP_ATOMIC, they still call
synchronize_rcu() which may block. Now I'm not familiar with the netlink code,
but I think that in general the flags are useless for GFP_ATOMIC because of the
calls to synchronize_rcu() in expand/shrink which can block anyway.
Just a thought, I may be missing something of course.

Nik
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/