mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-07 03:18:31 +00:00
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: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
bed1be2086
commit
f5c5440d40
2 changed files with 13 additions and 6 deletions
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue