Commit 356e2adb authored by Florian Westphal's avatar Florian Westphal
Browse files

netfilter: nfnetlink_log: remove rcu_bh usage



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: default avatarFlorian Westphal <fw@strlen.de>
parent da617cd8
Loading
Loading
Loading
Loading
+23 −13
Original line number Diff line number Diff line
@@ -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)