netfilter: flowtable: Add pending bit for offload work
Gc step can queue offloaded flow del work or stats work. Those work items can race each other and a flow could be freed before the stats work is executed and querying it. To avoid that, add a pending bit that if a work exists for a flow don't queue another work for it. This will also avoid adding multiple stats works in case stats work didn't complete but gc step started again. Signed-off-by: Paul Blakey <paulb@mellanox.com> Reviewed-by: Roi Dayan <roid@mellanox.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
2c407aca64
Коммит
2c8897953f
|
@ -127,6 +127,7 @@ enum nf_flow_flags {
|
|||
NF_FLOW_HW_DYING,
|
||||
NF_FLOW_HW_DEAD,
|
||||
NF_FLOW_HW_REFRESH,
|
||||
NF_FLOW_HW_PENDING,
|
||||
};
|
||||
|
||||
enum flow_offload_type {
|
||||
|
|
|
@ -817,6 +817,7 @@ static void flow_offload_work_handler(struct work_struct *work)
|
|||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
clear_bit(NF_FLOW_HW_PENDING, &offload->flow->flags);
|
||||
kfree(offload);
|
||||
}
|
||||
|
||||
|
@ -831,10 +832,15 @@ nf_flow_offload_work_alloc(struct nf_flowtable *flowtable,
|
|||
{
|
||||
struct flow_offload_work *offload;
|
||||
|
||||
offload = kmalloc(sizeof(struct flow_offload_work), GFP_ATOMIC);
|
||||
if (!offload)
|
||||
if (test_and_set_bit(NF_FLOW_HW_PENDING, &flow->flags))
|
||||
return NULL;
|
||||
|
||||
offload = kmalloc(sizeof(struct flow_offload_work), GFP_ATOMIC);
|
||||
if (!offload) {
|
||||
clear_bit(NF_FLOW_HW_PENDING, &flow->flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offload->cmd = cmd;
|
||||
offload->flow = flow;
|
||||
offload->priority = flowtable->priority;
|
||||
|
|
Загрузка…
Ссылка в новой задаче