netfilter: nfnetlink_log: remove rcu_bh usage
authorFlorian Westphal <fw@strlen.de>
Tue, 28 Mar 2023 16:44:15 +0000 (18:44 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 30 Mar 2023 20:20:09 +0000 (22:20 +0200)
structure is free'd via call_rcu, so its safe to use rcu_read_lock only.

While at it, skip rcu_read_lock for lookup from packet path, its always
called with rcu held.

Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nfnetlink_log.c

index d97eb28..e57eb16 100644 (file)
@@ -103,9 +103,9 @@ static inline u_int8_t instance_hashfn(u_int16_t group_num)
 }
 
 static struct nfulnl_instance *
-__instance_lookup(struct nfnl_log_net *log, u_int16_t group_num)
+__instance_lookup(const struct nfnl_log_net *log, u16 group_num)
 {
-       struct hlist_head *head;
+       const struct hlist_head *head;
        struct nfulnl_instance *inst;
 
        head = &log->instance_table[instance_hashfn(group_num)];
@@ -123,15 +123,25 @@ instance_get(struct nfulnl_instance *inst)
 }
 
 static struct nfulnl_instance *
-instance_lookup_get(struct nfnl_log_net *log, u_int16_t group_num)
+instance_lookup_get_rcu(const struct nfnl_log_net *log, u16 group_num)
 {
        struct nfulnl_instance *inst;
 
-       rcu_read_lock_bh();
        inst = __instance_lookup(log, group_num);
        if (inst && !refcount_inc_not_zero(&inst->use))
                inst = NULL;
-       rcu_read_unlock_bh();
+
+       return inst;
+}
+
+static struct nfulnl_instance *
+instance_lookup_get(const struct nfnl_log_net *log, u16 group_num)
+{
+       struct nfulnl_instance *inst;
+
+       rcu_read_lock();
+       inst = instance_lookup_get_rcu(log, group_num);
+       rcu_read_unlock();
 
        return inst;
 }
@@ -698,7 +708,7 @@ nfulnl_log_packet(struct net *net,
        else
                li = &default_loginfo;
 
-       inst = instance_lookup_get(log, li->u.ulog.group);
+       inst = instance_lookup_get_rcu(log, li->u.ulog.group);
        if (!inst)
                return;
 
@@ -1030,7 +1040,7 @@ static struct hlist_node *get_first(struct net *net, struct iter_state *st)
                struct hlist_head *head = &log->instance_table[st->bucket];
 
                if (!hlist_empty(head))
-                       return rcu_dereference_bh(hlist_first_rcu(head));
+                       return rcu_dereference(hlist_first_rcu(head));
        }
        return NULL;
 }
@@ -1038,7 +1048,7 @@ static struct hlist_node *get_first(struct net *net, struct iter_state *st)
 static struct hlist_node *get_next(struct net *net, struct iter_state *st,
                                   struct hlist_node *h)
 {
-       h = rcu_dereference_bh(hlist_next_rcu(h));
+       h = rcu_dereference(hlist_next_rcu(h));
        while (!h) {
                struct nfnl_log_net *log;
                struct hlist_head *head;
@@ -1048,7 +1058,7 @@ static struct hlist_node *get_next(struct net *net, struct iter_state *st,
 
                log = nfnl_log_pernet(net);
                head = &log->instance_table[st->bucket];
-               h = rcu_dereference_bh(hlist_first_rcu(head));
+               h = rcu_dereference(hlist_first_rcu(head));
        }
        return h;
 }
@@ -1066,9 +1076,9 @@ static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
 }
 
 static void *seq_start(struct seq_file *s, loff_t *pos)
-       __acquires(rcu_bh)
+       __acquires(rcu)
 {
-       rcu_read_lock_bh();
+       rcu_read_lock();
        return get_idx(seq_file_net(s), s->private, *pos);
 }
 
@@ -1079,9 +1089,9 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void seq_stop(struct seq_file *s, void *v)
-       __releases(rcu_bh)
+       __releases(rcu)
 {
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 }
 
 static int seq_show(struct seq_file *s, void *v)