Commit f5c5440d authored by Eric Dumazet's avatar Eric Dumazet Committed by Patrick McHardy

netfilter: nfnetlink_log: RCU conversion, part 2

- must use atomic_inc_not_zero() in instance_lookup_get()

- must use hlist_add_head_rcu() instead of hlist_add_head()

- must use hlist_del_rcu() instead of hlist_del()

- Introduce NFULNL_COPY_DISABLED to stop lockless reader from using an
instance, before we do final instance_put() on it.
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent bed1be20
...@@ -89,6 +89,7 @@ enum nfulnl_attr_config { ...@@ -89,6 +89,7 @@ enum nfulnl_attr_config {
#define NFULNL_COPY_NONE 0x00 #define NFULNL_COPY_NONE 0x00
#define NFULNL_COPY_META 0x01 #define NFULNL_COPY_META 0x01
#define NFULNL_COPY_PACKET 0x02 #define NFULNL_COPY_PACKET 0x02
#define NFULNL_COPY_DISABLED 0x03
#define NFULNL_CFG_F_SEQ 0x0001 #define NFULNL_CFG_F_SEQ 0x0001
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002 #define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
......
...@@ -109,8 +109,8 @@ instance_lookup_get(u_int16_t group_num) ...@@ -109,8 +109,8 @@ instance_lookup_get(u_int16_t group_num)
rcu_read_lock_bh(); rcu_read_lock_bh();
inst = __instance_lookup(group_num); inst = __instance_lookup(group_num);
if (inst) if (inst && !atomic_inc_not_zero(&inst->use))
instance_get(inst); inst = NULL;
rcu_read_unlock_bh(); rcu_read_unlock_bh();
return inst; return inst;
...@@ -171,7 +171,7 @@ instance_create(u_int16_t group_num, int pid) ...@@ -171,7 +171,7 @@ instance_create(u_int16_t group_num, int pid)
inst->copy_mode = NFULNL_COPY_PACKET; inst->copy_mode = NFULNL_COPY_PACKET;
inst->copy_range = NFULNL_COPY_RANGE_MAX; inst->copy_range = NFULNL_COPY_RANGE_MAX;
hlist_add_head(&inst->hlist, hlist_add_head_rcu(&inst->hlist,
&instance_table[instance_hashfn(group_num)]); &instance_table[instance_hashfn(group_num)]);
spin_unlock_bh(&instances_lock); spin_unlock_bh(&instances_lock);
...@@ -185,18 +185,23 @@ instance_create(u_int16_t group_num, int pid) ...@@ -185,18 +185,23 @@ instance_create(u_int16_t group_num, int pid)
static void __nfulnl_flush(struct nfulnl_instance *inst); static void __nfulnl_flush(struct nfulnl_instance *inst);
/* called with BH disabled */
static void static void
__instance_destroy(struct nfulnl_instance *inst) __instance_destroy(struct nfulnl_instance *inst)
{ {
/* first pull it out of the global list */ /* first pull it out of the global list */
hlist_del(&inst->hlist); hlist_del_rcu(&inst->hlist);
/* then flush all pending packets from skb */ /* then flush all pending packets from skb */
spin_lock_bh(&inst->lock); spin_lock(&inst->lock);
/* lockless readers wont be able to use us */
inst->copy_mode = NFULNL_COPY_DISABLED;
if (inst->skb) if (inst->skb)
__nfulnl_flush(inst); __nfulnl_flush(inst);
spin_unlock_bh(&inst->lock); spin_unlock(&inst->lock);
/* and finally put the refcount */ /* and finally put the refcount */
instance_put(inst); instance_put(inst);
...@@ -624,6 +629,7 @@ nfulnl_log_packet(u_int8_t pf, ...@@ -624,6 +629,7 @@ nfulnl_log_packet(u_int8_t pf,
size += nla_total_size(data_len); size += nla_total_size(data_len);
break; break;
case NFULNL_COPY_DISABLED:
default: default:
goto unlock_and_release; goto unlock_and_release;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment