net: sched: notify classifier on successful offload add/delete
To remove dependency on rtnl lock, extend classifier ops with new ops->hw_add() and ops->hw_del() callbacks. Call them from cls API while holding cb_lock every time filter if successfully added to or deleted from hardware. Implement the new API in flower classifier. Use it to manage hw_filters list under cb_lock protection, instead of relying on rtnl lock to synchronize with concurrent fl_reoffload() call. Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
4011921137
commit
a449a3e77a
@@ -3099,6 +3099,11 @@ int tc_setup_cb_add(struct tcf_block *block, struct tcf_proto *tp,
|
||||
}
|
||||
|
||||
ok_count = __tc_setup_cb_call(block, type, type_data, err_stop);
|
||||
if (ok_count < 0)
|
||||
goto err_unlock;
|
||||
|
||||
if (tp->ops->hw_add)
|
||||
tp->ops->hw_add(tp, type_data);
|
||||
if (ok_count > 0)
|
||||
tc_cls_offload_cnt_update(block, tp, in_hw_count, flags,
|
||||
ok_count, true);
|
||||
@@ -3130,11 +3135,18 @@ int tc_setup_cb_replace(struct tcf_block *block, struct tcf_proto *tp,
|
||||
}
|
||||
|
||||
tc_cls_offload_cnt_reset(block, tp, old_in_hw_count, old_flags);
|
||||
if (tp->ops->hw_del)
|
||||
tp->ops->hw_del(tp, type_data);
|
||||
|
||||
ok_count = __tc_setup_cb_call(block, type, type_data, err_stop);
|
||||
if (ok_count < 0)
|
||||
goto err_unlock;
|
||||
|
||||
if (tp->ops->hw_add)
|
||||
tp->ops->hw_add(tp, type_data);
|
||||
if (ok_count > 0)
|
||||
tc_cls_offload_cnt_update(block, tp, new_in_hw_count, new_flags,
|
||||
ok_count, true);
|
||||
tc_cls_offload_cnt_update(block, tp, new_in_hw_count,
|
||||
new_flags, ok_count, true);
|
||||
err_unlock:
|
||||
up_read(&block->cb_lock);
|
||||
return ok_count < 0 ? ok_count : 0;
|
||||
@@ -3155,6 +3167,9 @@ int tc_setup_cb_destroy(struct tcf_block *block, struct tcf_proto *tp,
|
||||
ok_count = __tc_setup_cb_call(block, type, type_data, err_stop);
|
||||
|
||||
tc_cls_offload_cnt_reset(block, tp, in_hw_count, flags);
|
||||
if (tp->ops->hw_del)
|
||||
tp->ops->hw_del(tp, type_data);
|
||||
|
||||
up_read(&block->cb_lock);
|
||||
return ok_count < 0 ? ok_count : 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user