Commit ace4a267 authored by Vlad Buslov's avatar Vlad Buslov Committed by David S. Miller

net: sched: don't release block->lock when dumping chains

Function tc_dump_chain() obtains and releases block->lock on each iteration
of its inner loop that dumps all chains on block. Outputting chain template
info is fast operation so locking/unlocking mutex multiple times is an
overhead when lock is highly contested. Modify tc_dump_chain() to only
obtain block->lock once and dump all chains without releasing it.
Signed-off-by: default avatarVlad Buslov <vladbu@mellanox.com>
Suggested-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6676d5e4
...@@ -2912,12 +2912,12 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -2912,12 +2912,12 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n,
/* called with RTNL */ /* called with RTNL */
static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb) static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct tcf_chain *chain, *chain_prev;
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct nlattr *tca[TCA_MAX + 1]; struct nlattr *tca[TCA_MAX + 1];
struct Qdisc *q = NULL; struct Qdisc *q = NULL;
struct tcf_block *block; struct tcf_block *block;
struct tcmsg *tcm = nlmsg_data(cb->nlh); struct tcmsg *tcm = nlmsg_data(cb->nlh);
struct tcf_chain *chain;
long index_start; long index_start;
long index; long index;
u32 parent; u32 parent;
...@@ -2980,11 +2980,8 @@ static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2980,11 +2980,8 @@ static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb)
index_start = cb->args[0]; index_start = cb->args[0];
index = 0; index = 0;
for (chain = __tcf_get_next_chain(block, NULL); mutex_lock(&block->lock);
chain; list_for_each_entry(chain, &block->chain_list, list) {
chain_prev = chain,
chain = __tcf_get_next_chain(block, chain),
tcf_chain_put(chain_prev)) {
if ((tca[TCA_CHAIN] && if ((tca[TCA_CHAIN] &&
nla_get_u32(tca[TCA_CHAIN]) != chain->index)) nla_get_u32(tca[TCA_CHAIN]) != chain->index))
continue; continue;
...@@ -2992,17 +2989,18 @@ static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2992,17 +2989,18 @@ static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb)
index++; index++;
continue; continue;
} }
if (tcf_chain_held_by_acts_only(chain))
continue;
err = tc_chain_fill_node(chain->tmplt_ops, chain->tmplt_priv, err = tc_chain_fill_node(chain->tmplt_ops, chain->tmplt_priv,
chain->index, net, skb, block, chain->index, net, skb, block,
NETLINK_CB(cb->skb).portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh->nlmsg_seq, NLM_F_MULTI,
RTM_NEWCHAIN); RTM_NEWCHAIN);
if (err <= 0) { if (err <= 0)
tcf_chain_put(chain);
break; break;
}
index++; index++;
} }
mutex_unlock(&block->lock);
if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK)
tcf_block_refcnt_put(block, true); tcf_block_refcnt_put(block, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment