diff options
-rw-r--r-- | include/linux/bpf_mprog.h | 16 | ||||
-rw-r--r-- | kernel/bpf/tcx.c | 12 |
2 files changed, 24 insertions, 4 deletions
diff --git a/include/linux/bpf_mprog.h b/include/linux/bpf_mprog.h index 2b429488f840..929225f7b095 100644 --- a/include/linux/bpf_mprog.h +++ b/include/linux/bpf_mprog.h @@ -256,6 +256,22 @@ static inline void bpf_mprog_entry_copy(struct bpf_mprog_entry *dst, memcpy(dst->fp_items, src->fp_items, sizeof(src->fp_items)); } +static inline void bpf_mprog_entry_clear(struct bpf_mprog_entry *dst) +{ + memset(dst->fp_items, 0, sizeof(dst->fp_items)); +} + +static inline void bpf_mprog_clear_all(struct bpf_mprog_entry *entry, + struct bpf_mprog_entry **entry_new) +{ + struct bpf_mprog_entry *peer; + + peer = bpf_mprog_peer(entry); + bpf_mprog_entry_clear(peer); + peer->parent->count = 0; + *entry_new = peer; +} + static inline void bpf_mprog_entry_grow(struct bpf_mprog_entry *entry, int idx) { int total = bpf_mprog_total(entry); diff --git a/kernel/bpf/tcx.c b/kernel/bpf/tcx.c index 69a272712b29..13f0b5dc8262 100644 --- a/kernel/bpf/tcx.c +++ b/kernel/bpf/tcx.c @@ -94,15 +94,19 @@ out: void tcx_uninstall(struct net_device *dev, bool ingress) { + struct bpf_mprog_entry *entry, *entry_new = NULL; struct bpf_tuple tuple = {}; - struct bpf_mprog_entry *entry; struct bpf_mprog_fp *fp; struct bpf_mprog_cp *cp; + bool active; entry = tcx_entry_fetch(dev, ingress); if (!entry) return; - tcx_entry_update(dev, NULL, ingress); + active = tcx_entry(entry)->miniq_active; + if (active) + bpf_mprog_clear_all(entry, &entry_new); + tcx_entry_update(dev, entry_new, ingress); tcx_entry_sync(); bpf_mprog_foreach_tuple(entry, fp, cp, tuple) { if (tuple.link) @@ -111,8 +115,8 @@ void tcx_uninstall(struct net_device *dev, bool ingress) bpf_prog_put(tuple.prog); tcx_skeys_dec(ingress); } - WARN_ON_ONCE(tcx_entry(entry)->miniq_active); - tcx_entry_free(entry); + if (!active) + tcx_entry_free(entry); } int tcx_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr) |