提交 339c21d7 编写于 作者: J Jiri Pirko 提交者: David S. Miller

net: sched: fix tc_u_common lookup

The offending commit wrongly assumes 1:1 mapping between block and q.
However, there are multiple blocks for a single q for classful qdiscs.
Since the obscure tc_u_common sharing mechanism expects it to be shared
among a qdisc, fix it by storing q pointer in case the block is not
shared.
Reported-by: NPaweł Staszewski <pstaszewski@itcare.pl>
Reported-by: NCong Wang <xiyou.wangcong@gmail.com>
Fixes: 7fa9d974 ("net: sched: cls_u32: use block instead of q in tc_u_common")
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 bb047ddd
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
...@@ -96,7 +96,7 @@ struct tc_u_hnode { ...@@ -96,7 +96,7 @@ struct tc_u_hnode {
struct tc_u_common { struct tc_u_common {
struct tc_u_hnode __rcu *hlist; struct tc_u_hnode __rcu *hlist;
struct tcf_block *block; void *ptr;
int refcnt; int refcnt;
struct idr handle_idr; struct idr handle_idr;
struct hlist_node hnode; struct hlist_node hnode;
...@@ -330,9 +330,25 @@ static struct hlist_head *tc_u_common_hash; ...@@ -330,9 +330,25 @@ static struct hlist_head *tc_u_common_hash;
#define U32_HASH_SHIFT 10 #define U32_HASH_SHIFT 10
#define U32_HASH_SIZE (1 << U32_HASH_SHIFT) #define U32_HASH_SIZE (1 << U32_HASH_SHIFT)
static void *tc_u_common_ptr(const struct tcf_proto *tp)
{
struct tcf_block *block = tp->chain->block;
/* The block sharing is currently supported only
* for classless qdiscs. In that case we use block
* for tc_u_common identification. In case the
* block is not shared, block->q is a valid pointer
* and we can use that. That works for classful qdiscs.
*/
if (tcf_block_shared(block))
return block;
else
return block->q;
}
static unsigned int tc_u_hash(const struct tcf_proto *tp) static unsigned int tc_u_hash(const struct tcf_proto *tp)
{ {
return hash_ptr(tp->chain->block, U32_HASH_SHIFT); return hash_ptr(tc_u_common_ptr(tp), U32_HASH_SHIFT);
} }
static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp) static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp)
...@@ -342,7 +358,7 @@ static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp) ...@@ -342,7 +358,7 @@ static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp)
h = tc_u_hash(tp); h = tc_u_hash(tp);
hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) { hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) {
if (tc->block == tp->chain->block) if (tc->ptr == tc_u_common_ptr(tp))
return tc; return tc;
} }
return NULL; return NULL;
...@@ -371,7 +387,7 @@ static int u32_init(struct tcf_proto *tp) ...@@ -371,7 +387,7 @@ static int u32_init(struct tcf_proto *tp)
kfree(root_ht); kfree(root_ht);
return -ENOBUFS; return -ENOBUFS;
} }
tp_c->block = tp->chain->block; tp_c->ptr = tc_u_common_ptr(tp);
INIT_HLIST_NODE(&tp_c->hnode); INIT_HLIST_NODE(&tp_c->hnode);
idr_init(&tp_c->handle_idr); idr_init(&tp_c->handle_idr);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部