Skip to content

Commit ca065d0

Browse files
Eric Dumazetdavem330
authored andcommitted
udp: no longer use SLAB_DESTROY_BY_RCU
Tom Herbert would like not touching UDP socket refcnt for encapsulated traffic. For this to happen, we need to use normal RCU rules, with a grace period before freeing a socket. UDP sockets are not short lived in the high usage case, so the added cost of call_rcu() should not be a concern. This actually removes a lot of complexity in UDP stack. Multicast receives no longer need to hold a bucket spinlock. Note that ip early demux still needs to take a reference on the socket. Same remark for functions used by xt_socket and xt_PROXY netfilter modules, but this might be changed later. Performance for a single UDP socket receiving flood traffic from many RX queues/cpus. Simple udp_rx using simple recvfrom() loop : 438 kpps instead of 374 kpps : 17 % increase of the peak rate. v2: Addressed Willem de Bruijn feedback in multicast handling - keep early demux break in __udp4_lib_demux_lookup() Signed-off-by: Eric Dumazet <[email protected]> Cc: Tom Herbert <[email protected]> Cc: Willem de Bruijn <[email protected]> Tested-by: Tom Herbert <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a4298e4 commit ca065d0

File tree

6 files changed

+171
-358
lines changed

6 files changed

+171
-358
lines changed

include/linux/udp.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ static inline bool udp_get_no_check6_rx(struct sock *sk)
9898
return udp_sk(sk)->no_check6_rx;
9999
}
100100

101-
#define udp_portaddr_for_each_entry(__sk, node, list) \
102-
hlist_nulls_for_each_entry(__sk, node, list, __sk_common.skc_portaddr_node)
101+
#define udp_portaddr_for_each_entry(__sk, list) \
102+
hlist_for_each_entry(__sk, list, __sk_common.skc_portaddr_node)
103103

104-
#define udp_portaddr_for_each_entry_rcu(__sk, node, list) \
105-
hlist_nulls_for_each_entry_rcu(__sk, node, list, __sk_common.skc_portaddr_node)
104+
#define udp_portaddr_for_each_entry_rcu(__sk, list) \
105+
hlist_for_each_entry_rcu(__sk, list, __sk_common.skc_portaddr_node)
106106

107107
#define IS_UDPLITE(__sk) (udp_sk(__sk)->pcflag)
108108

include/net/sock.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ struct sock_common {
178178
int skc_bound_dev_if;
179179
union {
180180
struct hlist_node skc_bind_node;
181-
struct hlist_nulls_node skc_portaddr_node;
181+
struct hlist_node skc_portaddr_node;
182182
};
183183
struct proto *skc_prot;
184184
possible_net_t skc_net;
@@ -670,18 +670,18 @@ static inline void sk_add_bind_node(struct sock *sk,
670670
hlist_for_each_entry(__sk, list, sk_bind_node)
671671

672672
/**
673-
* sk_nulls_for_each_entry_offset - iterate over a list at a given struct offset
673+
* sk_for_each_entry_offset_rcu - iterate over a list at a given struct offset
674674
* @tpos: the type * to use as a loop cursor.
675675
* @pos: the &struct hlist_node to use as a loop cursor.
676676
* @head: the head for your list.
677677
* @offset: offset of hlist_node within the struct.
678678
*
679679
*/
680-
#define sk_nulls_for_each_entry_offset(tpos, pos, head, offset) \
681-
for (pos = (head)->first; \
682-
(!is_a_nulls(pos)) && \
680+
#define sk_for_each_entry_offset_rcu(tpos, pos, head, offset) \
681+
for (pos = rcu_dereference((head)->first); \
682+
pos != NULL && \
683683
({ tpos = (typeof(*tpos) *)((void *)pos - offset); 1;}); \
684-
pos = pos->next)
684+
pos = rcu_dereference(pos->next))
685685

686686
static inline struct user_namespace *sk_user_ns(struct sock *sk)
687687
{

include/net/udp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct udp_skb_cb {
5959
* @lock: spinlock protecting changes to head/count
6060
*/
6161
struct udp_hslot {
62-
struct hlist_nulls_head head;
62+
struct hlist_head head;
6363
int count;
6464
spinlock_t lock;
6565
} __attribute__((aligned(2 * sizeof(long))));

0 commit comments

Comments
 (0)