summaryrefslogtreecommitdiff
path: root/net/sched/cls_u32.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2018-02-07 15:54:20 -0700
committerJens Axboe <axboe@kernel.dk>2018-02-07 15:54:20 -0700
commit61a695184fcc8f225327206b88320279dd8684af (patch)
tree6cbda2b0e7de94ebad95072d17cc0aa82c9d8ab3 /net/sched/cls_u32.c
parent9e05c864993c5442227f83ae1694a737d7a102ed (diff)
parent581e400ff935d34d95811258586128bf11baef15 (diff)
Merge branch 'master' into test
* master: (1190 commits) ASoC: stm32: add of dependency for stm32 drivers ASoC: mt8173-rt5650: fix child-node lookup ASoC: dapm: fix debugfs read using path->connected platform/x86: samsung-laptop: Re-use DEFINE_SHOW_ATTRIBUTE() macro platform/x86: ideapad-laptop: Re-use DEFINE_SHOW_ATTRIBUTE() macro platform/x86: dell-laptop: Re-use DEFINE_SHOW_ATTRIBUTE() macro seq_file: Introduce DEFINE_SHOW_ATTRIBUTE() helper macro Documentation/sysctl/user.txt: fix typo MAINTAINERS: update ARM/QUALCOMM SUPPORT patterns MAINTAINERS: update various PALM patterns MAINTAINERS: update "ARM/OXNAS platform support" patterns MAINTAINERS: update Cortina/Gemini patterns MAINTAINERS: remove ARM/CLKDEV SUPPORT file pattern MAINTAINERS: remove ANDROID ION pattern mm: docs: add blank lines to silence sphinx "Unexpected indentation" errors mm: docs: fix parameter names mismatch mm: docs: fixup punctuation pipe: read buffer limits atomically pipe: simplify round_pipe_size() pipe: reject F_SETPIPE_SZ with size over UINT_MAX ...
Diffstat (limited to 'net/sched/cls_u32.c')
-rw-r--r--net/sched/cls_u32.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index e3c5e390ec23..6311a548046b 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -398,10 +398,12 @@ static int u32_init(struct tcf_proto *tp)
static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
bool free_pf)
{
+ struct tc_u_hnode *ht = rtnl_dereference(n->ht_down);
+
tcf_exts_destroy(&n->exts);
tcf_exts_put_net(&n->exts);
- if (n->ht_down)
- n->ht_down->refcnt--;
+ if (ht && --ht->refcnt == 0)
+ kfree(ht);
#ifdef CONFIG_CLS_U32_PERF
if (free_pf)
free_percpu(n->pf);
@@ -659,16 +661,15 @@ static void u32_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
hlist_del(&tp_c->hnode);
- for (ht = rtnl_dereference(tp_c->hlist);
- ht;
- ht = rtnl_dereference(ht->next)) {
- ht->refcnt--;
- u32_clear_hnode(tp, ht, extack);
- }
-
while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) {
+ u32_clear_hnode(tp, ht, extack);
RCU_INIT_POINTER(tp_c->hlist, ht->next);
- kfree_rcu(ht, rcu);
+
+ /* u32_destroy_key() will later free ht for us, if it's
+ * still referenced by some knode
+ */
+ if (--ht->refcnt == 0)
+ kfree_rcu(ht, rcu);
}
idr_destroy(&tp_c->handle_idr);