Commit 745482e0 authored by David S. Miller's avatar David S. Miller

Merge branch 'sched-tp_q-remove'

Jiri Pirko <jiri@mellanox.com>

====================
net: sched: remove some tp->q usage

In order to prepare for block sharing, tcf_proto instances need to be
independent on particular qdisc instances. This patchset takes care of
removal of couple occurrences of tp->q usage.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 32302902 a10fa201
...@@ -22,15 +22,26 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, ...@@ -22,15 +22,26 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
bool create); bool create);
void tcf_chain_put(struct tcf_chain *chain); void tcf_chain_put(struct tcf_chain *chain);
int tcf_block_get(struct tcf_block **p_block, int tcf_block_get(struct tcf_block **p_block,
struct tcf_proto __rcu **p_filter_chain); struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q);
void tcf_block_put(struct tcf_block *block); void tcf_block_put(struct tcf_block *block);
static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
{
return block->q;
}
static inline struct net_device *tcf_block_dev(struct tcf_block *block)
{
return tcf_block_q(block)->dev_queue->dev;
}
int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
struct tcf_result *res, bool compat_mode); struct tcf_result *res, bool compat_mode);
#else #else
static inline static inline
int tcf_block_get(struct tcf_block **p_block, int tcf_block_get(struct tcf_block **p_block,
struct tcf_proto __rcu **p_filter_chain) struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
{ {
return 0; return 0;
} }
...@@ -39,6 +50,16 @@ static inline void tcf_block_put(struct tcf_block *block) ...@@ -39,6 +50,16 @@ static inline void tcf_block_put(struct tcf_block *block)
{ {
} }
static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
{
return NULL;
}
static inline struct net_device *tcf_block_dev(struct tcf_block *block)
{
return NULL;
}
static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
struct tcf_result *res, bool compat_mode) struct tcf_result *res, bool compat_mode)
{ {
...@@ -53,36 +74,43 @@ __cls_set_class(unsigned long *clp, unsigned long cl) ...@@ -53,36 +74,43 @@ __cls_set_class(unsigned long *clp, unsigned long cl)
} }
static inline unsigned long static inline unsigned long
cls_set_class(struct tcf_proto *tp, unsigned long *clp, cls_set_class(struct Qdisc *q, unsigned long *clp, unsigned long cl)
unsigned long cl)
{ {
unsigned long old_cl; unsigned long old_cl;
tcf_tree_lock(tp); sch_tree_lock(q);
old_cl = __cls_set_class(clp, cl); old_cl = __cls_set_class(clp, cl);
tcf_tree_unlock(tp); sch_tree_unlock(q);
return old_cl; return old_cl;
} }
static inline void static inline void
tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base) tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
{ {
struct Qdisc *q = tp->chain->block->q;
unsigned long cl; unsigned long cl;
cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid); /* Check q as it is not set for shared blocks. In that case,
cl = cls_set_class(tp, &r->class, cl); * setting class is not supported.
*/
if (!q)
return;
cl = q->ops->cl_ops->bind_tcf(q, base, r->classid);
cl = cls_set_class(q, &r->class, cl);
if (cl) if (cl)
tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); q->ops->cl_ops->unbind_tcf(q, cl);
} }
static inline void static inline void
tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r) tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
{ {
struct Qdisc *q = tp->chain->block->q;
unsigned long cl; unsigned long cl;
if (!q)
return;
if ((cl = __cls_set_class(&r->class, 0)) != 0) if ((cl = __cls_set_class(&r->class, 0)) != 0)
tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); q->ops->cl_ops->unbind_tcf(q, cl);
} }
struct tcf_exts { struct tcf_exts {
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/netdevice.h>
#include <net/sch_generic.h> #include <net/sch_generic.h>
#include <net/net_namespace.h>
#include <uapi/linux/pkt_sched.h> #include <uapi/linux/pkt_sched.h>
#define DEFAULT_TX_QUEUE_LEN 1000 #define DEFAULT_TX_QUEUE_LEN 1000
...@@ -146,4 +148,9 @@ static inline bool is_classid_clsact_egress(u32 classid) ...@@ -146,4 +148,9 @@ static inline bool is_classid_clsact_egress(u32 classid)
TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_EGRESS); TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_EGRESS);
} }
static inline struct net *qdisc_net(struct Qdisc *q)
{
return dev_net(q->dev_queue->dev);
}
#endif #endif
...@@ -270,6 +270,8 @@ struct tcf_chain { ...@@ -270,6 +270,8 @@ struct tcf_chain {
struct tcf_block { struct tcf_block {
struct list_head chain_list; struct list_head chain_list;
struct net *net;
struct Qdisc *q;
}; };
static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
...@@ -357,9 +359,6 @@ static inline void sch_tree_unlock(const struct Qdisc *q) ...@@ -357,9 +359,6 @@ static inline void sch_tree_unlock(const struct Qdisc *q)
spin_unlock_bh(qdisc_root_sleeping_lock(q)); spin_unlock_bh(qdisc_root_sleeping_lock(q));
} }
#define tcf_tree_lock(tp) sch_tree_lock((tp)->q)
#define tcf_tree_unlock(tp) sch_tree_unlock((tp)->q)
extern struct Qdisc noop_qdisc; extern struct Qdisc noop_qdisc;
extern struct Qdisc_ops noop_qdisc_ops; extern struct Qdisc_ops noop_qdisc_ops;
extern struct Qdisc_ops pfifo_fast_ops; extern struct Qdisc_ops pfifo_fast_ops;
......
...@@ -241,7 +241,7 @@ tcf_chain_filter_chain_ptr_set(struct tcf_chain *chain, ...@@ -241,7 +241,7 @@ tcf_chain_filter_chain_ptr_set(struct tcf_chain *chain,
} }
int tcf_block_get(struct tcf_block **p_block, int tcf_block_get(struct tcf_block **p_block,
struct tcf_proto __rcu **p_filter_chain) struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
{ {
struct tcf_block *block = kzalloc(sizeof(*block), GFP_KERNEL); struct tcf_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
struct tcf_chain *chain; struct tcf_chain *chain;
...@@ -257,6 +257,8 @@ int tcf_block_get(struct tcf_block **p_block, ...@@ -257,6 +257,8 @@ int tcf_block_get(struct tcf_block **p_block,
goto err_chain_create; goto err_chain_create;
} }
tcf_chain_filter_chain_ptr_set(chain, p_filter_chain); tcf_chain_filter_chain_ptr_set(chain, p_filter_chain);
block->net = qdisc_net(q);
block->q = q;
*p_block = block; *p_block = block;
return 0; return 0;
...@@ -418,8 +420,8 @@ static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain, ...@@ -418,8 +420,8 @@ static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain,
} }
static int tcf_fill_node(struct net *net, struct sk_buff *skb, static int tcf_fill_node(struct net *net, struct sk_buff *skb,
struct tcf_proto *tp, void *fh, u32 portid, struct tcf_proto *tp, struct Qdisc *q, u32 parent,
u32 seq, u16 flags, int event) void *fh, u32 portid, u32 seq, u16 flags, int event)
{ {
struct tcmsg *tcm; struct tcmsg *tcm;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
...@@ -432,8 +434,8 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb, ...@@ -432,8 +434,8 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
tcm->tcm_family = AF_UNSPEC; tcm->tcm_family = AF_UNSPEC;
tcm->tcm__pad1 = 0; tcm->tcm__pad1 = 0;
tcm->tcm__pad2 = 0; tcm->tcm__pad2 = 0;
tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
tcm->tcm_parent = tp->classid; tcm->tcm_parent = parent;
tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
if (nla_put_string(skb, TCA_KIND, tp->ops->kind)) if (nla_put_string(skb, TCA_KIND, tp->ops->kind))
goto nla_put_failure; goto nla_put_failure;
...@@ -456,6 +458,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb, ...@@ -456,6 +458,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
static int tfilter_notify(struct net *net, struct sk_buff *oskb, static int tfilter_notify(struct net *net, struct sk_buff *oskb,
struct nlmsghdr *n, struct tcf_proto *tp, struct nlmsghdr *n, struct tcf_proto *tp,
struct Qdisc *q, u32 parent,
void *fh, int event, bool unicast) void *fh, int event, bool unicast)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -465,7 +468,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, ...@@ -465,7 +468,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
if (!skb) if (!skb)
return -ENOBUFS; return -ENOBUFS;
if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, if (tcf_fill_node(net, skb, tp, q, parent, fh, portid, n->nlmsg_seq,
n->nlmsg_flags, event) <= 0) { n->nlmsg_flags, event) <= 0) {
kfree_skb(skb); kfree_skb(skb);
return -EINVAL; return -EINVAL;
...@@ -480,6 +483,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, ...@@ -480,6 +483,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
struct nlmsghdr *n, struct tcf_proto *tp, struct nlmsghdr *n, struct tcf_proto *tp,
struct Qdisc *q, u32 parent,
void *fh, bool unicast, bool *last) void *fh, bool unicast, bool *last)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -490,7 +494,7 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, ...@@ -490,7 +494,7 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
if (!skb) if (!skb)
return -ENOBUFS; return -ENOBUFS;
if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, if (tcf_fill_node(net, skb, tp, q, parent, fh, portid, n->nlmsg_seq,
n->nlmsg_flags, RTM_DELTFILTER) <= 0) { n->nlmsg_flags, RTM_DELTFILTER) <= 0) {
kfree_skb(skb); kfree_skb(skb);
return -EINVAL; return -EINVAL;
...@@ -510,6 +514,7 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, ...@@ -510,6 +514,7 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
} }
static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
struct Qdisc *q, u32 parent,
struct nlmsghdr *n, struct nlmsghdr *n,
struct tcf_chain *chain, int event) struct tcf_chain *chain, int event)
{ {
...@@ -517,7 +522,7 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, ...@@ -517,7 +522,7 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
for (tp = rtnl_dereference(chain->filter_chain); for (tp = rtnl_dereference(chain->filter_chain);
tp; tp = rtnl_dereference(tp->next)) tp; tp = rtnl_dereference(tp->next))
tfilter_notify(net, oskb, n, tp, 0, event, false); tfilter_notify(net, oskb, n, tp, q, parent, 0, event, false);
} }
/* Add/change/delete/get a filter node */ /* Add/change/delete/get a filter node */
...@@ -636,7 +641,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -636,7 +641,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
} }
if (n->nlmsg_type == RTM_DELTFILTER && prio == 0) { if (n->nlmsg_type == RTM_DELTFILTER && prio == 0) {
tfilter_notify_chain(net, skb, n, chain, RTM_DELTFILTER); tfilter_notify_chain(net, skb, q, parent, n,
chain, RTM_DELTFILTER);
tcf_chain_flush(chain); tcf_chain_flush(chain);
err = 0; err = 0;
goto errout; goto errout;
...@@ -683,7 +689,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -683,7 +689,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
if (!fh) { if (!fh) {
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
tcf_chain_tp_remove(chain, &chain_info, tp); tcf_chain_tp_remove(chain, &chain_info, tp);
tfilter_notify(net, skb, n, tp, fh, tfilter_notify(net, skb, n, tp, q, parent, fh,
RTM_DELTFILTER, false); RTM_DELTFILTER, false);
tcf_proto_destroy(tp); tcf_proto_destroy(tp);
err = 0; err = 0;
...@@ -708,8 +714,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -708,8 +714,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
} }
break; break;
case RTM_DELTFILTER: case RTM_DELTFILTER:
err = tfilter_del_notify(net, skb, n, tp, fh, false, err = tfilter_del_notify(net, skb, n, tp, q, parent,
&last); fh, false, &last);
if (err) if (err)
goto errout; goto errout;
if (last) { if (last) {
...@@ -718,7 +724,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -718,7 +724,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
} }
goto errout; goto errout;
case RTM_GETTFILTER: case RTM_GETTFILTER:
err = tfilter_notify(net, skb, n, tp, fh, err = tfilter_notify(net, skb, n, tp, q, parent, fh,
RTM_NEWTFILTER, true); RTM_NEWTFILTER, true);
goto errout; goto errout;
default: default:
...@@ -732,7 +738,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -732,7 +738,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
if (err == 0) { if (err == 0) {
if (tp_created) if (tp_created)
tcf_chain_tp_insert(chain, &chain_info, tp); tcf_chain_tp_insert(chain, &chain_info, tp);
tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false); tfilter_notify(net, skb, n, tp, q, parent, fh,
RTM_NEWTFILTER, false);
} else { } else {
if (tp_created) if (tp_created)
tcf_proto_destroy(tp); tcf_proto_destroy(tp);
...@@ -751,6 +758,8 @@ struct tcf_dump_args { ...@@ -751,6 +758,8 @@ struct tcf_dump_args {
struct tcf_walker w; struct tcf_walker w;
struct sk_buff *skb; struct sk_buff *skb;
struct netlink_callback *cb; struct netlink_callback *cb;
struct Qdisc *q;
u32 parent;
}; };
static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg) static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
...@@ -758,13 +767,14 @@ static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg) ...@@ -758,13 +767,14 @@ static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
struct tcf_dump_args *a = (void *)arg; struct tcf_dump_args *a = (void *)arg;
struct net *net = sock_net(a->skb->sk); struct net *net = sock_net(a->skb->sk);
return tcf_fill_node(net, a->skb, tp, n, NETLINK_CB(a->cb->skb).portid, return tcf_fill_node(net, a->skb, tp, a->q, a->parent,
n, NETLINK_CB(a->cb->skb).portid,
a->cb->nlh->nlmsg_seq, NLM_F_MULTI, a->cb->nlh->nlmsg_seq, NLM_F_MULTI,
RTM_NEWTFILTER); RTM_NEWTFILTER);
} }
static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb, static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent,
struct netlink_callback *cb, struct sk_buff *skb, struct netlink_callback *cb,
long index_start, long *p_index) long index_start, long *p_index)
{ {
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
...@@ -786,7 +796,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb, ...@@ -786,7 +796,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb,
memset(&cb->args[1], 0, memset(&cb->args[1], 0,
sizeof(cb->args) - sizeof(cb->args[0])); sizeof(cb->args) - sizeof(cb->args[0]));
if (cb->args[1] == 0) { if (cb->args[1] == 0) {
if (tcf_fill_node(net, skb, tp, 0, if (tcf_fill_node(net, skb, tp, q, parent, 0,
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_NEWTFILTER) <= 0) RTM_NEWTFILTER) <= 0)
...@@ -799,6 +809,8 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb, ...@@ -799,6 +809,8 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct sk_buff *skb,
arg.w.fn = tcf_node_dump; arg.w.fn = tcf_node_dump;
arg.skb = skb; arg.skb = skb;
arg.cb = cb; arg.cb = cb;
arg.q = q;
arg.parent = parent;
arg.w.stop = 0; arg.w.stop = 0;
arg.w.skip = cb->args[1] - 1; arg.w.skip = cb->args[1] - 1;
arg.w.count = 0; arg.w.count = 0;
...@@ -824,6 +836,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -824,6 +836,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
const struct Qdisc_class_ops *cops; const struct Qdisc_class_ops *cops;
long index_start; long index_start;
long index; long index;
u32 parent;
int err; int err;
if (nlmsg_len(cb->nlh) < sizeof(*tcm)) if (nlmsg_len(cb->nlh) < sizeof(*tcm))
...@@ -837,10 +850,13 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -837,10 +850,13 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
if (!dev) if (!dev)
return skb->len; return skb->len;
if (!tcm->tcm_parent) parent = tcm->tcm_parent;
if (!parent) {
q = dev->qdisc; q = dev->qdisc;
else parent = q->handle;
} else {
q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
}
if (!q) if (!q)
goto out; goto out;
cops = q->ops->cl_ops; cops = q->ops->cl_ops;
...@@ -864,7 +880,8 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -864,7 +880,8 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
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;
if (!tcf_chain_dump(chain, skb, cb, index_start, &index)) if (!tcf_chain_dump(chain, q, parent, skb, cb,
index_start, &index))
break; break;
} }
......
...@@ -491,8 +491,11 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, ...@@ -491,8 +491,11 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ; perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ;
} }
if (TC_H_MAJ(baseclass) == 0) if (TC_H_MAJ(baseclass) == 0) {
baseclass = TC_H_MAKE(tp->q->handle, baseclass); struct Qdisc *q = tcf_block_q(tp->chain->block);
baseclass = TC_H_MAKE(q->handle, baseclass);
}
if (TC_H_MIN(baseclass) == 0) if (TC_H_MIN(baseclass) == 0)
baseclass = TC_H_MAKE(baseclass, 1); baseclass = TC_H_MAKE(baseclass, 1);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/sch_generic.h>
#define HTSIZE 256 #define HTSIZE 256
...@@ -83,9 +84,11 @@ static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, ...@@ -83,9 +84,11 @@ static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp,
} }
} }
} else { } else {
struct Qdisc *q = tcf_block_q(tp->chain->block);
/* Old method: classify the packet using its skb mark. */ /* Old method: classify the packet using its skb mark. */
if (id && (TC_H_MAJ(id) == 0 || if (id && (TC_H_MAJ(id) == 0 ||
!(TC_H_MAJ(id ^ tp->q->handle)))) { !(TC_H_MAJ(id ^ q->handle)))) {
res->classid = id; res->classid = id;
res->class = 0; res->class = 0;
return 0; return 0;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <net/act_api.h> #include <net/act_api.h>
#include <net/netlink.h> #include <net/netlink.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/sch_generic.h>
/* /*
* Passing parameters to the root seems to be done more awkwardly than really * Passing parameters to the root seems to be done more awkwardly than really
...@@ -90,9 +91,11 @@ static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp, ...@@ -90,9 +91,11 @@ static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp,
f = tcindex_lookup(p, key); f = tcindex_lookup(p, key);
if (!f) { if (!f) {
struct Qdisc *q = tcf_block_q(tp->chain->block);
if (!p->fall_through) if (!p->fall_through)
return -1; return -1;
res->classid = TC_H_MAKE(TC_H_MAJ(tp->q->handle), key); res->classid = TC_H_MAKE(TC_H_MAJ(q->handle), key);
res->class = 0; res->class = 0;
pr_debug("alg 0x%x\n", res->classid); pr_debug("alg 0x%x\n", res->classid);
return 0; return 0;
......
...@@ -93,7 +93,7 @@ struct tc_u_hnode { ...@@ -93,7 +93,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 Qdisc *q; struct tcf_block *block;
int refcnt; int refcnt;
struct idr handle_idr; struct idr handle_idr;
struct hlist_node hnode; struct hlist_node hnode;
...@@ -335,11 +335,7 @@ static struct hlist_head *tc_u_common_hash; ...@@ -335,11 +335,7 @@ static struct hlist_head *tc_u_common_hash;
static unsigned int tc_u_hash(const struct tcf_proto *tp) static unsigned int tc_u_hash(const struct tcf_proto *tp)
{ {
struct net_device *dev = tp->q->dev_queue->dev; return hash_64((u64) tp->chain->block, U32_HASH_SHIFT);
u32 qhandle = tp->q->handle;
int ifindex = dev->ifindex;
return hash_64((u64)ifindex << 32 | qhandle, 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)
...@@ -349,7 +345,7 @@ static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp) ...@@ -349,7 +345,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->q == tp->q) if (tc->block == tp->chain->block)
return tc; return tc;
} }
return NULL; return NULL;
...@@ -378,7 +374,7 @@ static int u32_init(struct tcf_proto *tp) ...@@ -378,7 +374,7 @@ static int u32_init(struct tcf_proto *tp)
kfree(root_ht); kfree(root_ht);
return -ENOBUFS; return -ENOBUFS;
} }
tp_c->q = tp->q; tp_c->block = tp->chain->block;
INIT_HLIST_NODE(&tp_c->hnode); INIT_HLIST_NODE(&tp_c->hnode);
idr_init(&tp_c->handle_idr); idr_init(&tp_c->handle_idr);
......
...@@ -178,7 +178,7 @@ static int tcf_em_validate(struct tcf_proto *tp, ...@@ -178,7 +178,7 @@ static int tcf_em_validate(struct tcf_proto *tp,
struct tcf_ematch_hdr *em_hdr = nla_data(nla); struct tcf_ematch_hdr *em_hdr = nla_data(nla);
int data_len = nla_len(nla) - sizeof(*em_hdr); int data_len = nla_len(nla) - sizeof(*em_hdr);
void *data = (void *) em_hdr + sizeof(*em_hdr); void *data = (void *) em_hdr + sizeof(*em_hdr);
struct net *net = dev_net(qdisc_dev(tp->q)); struct net *net = tp->chain->block->net;
if (!TCF_EM_REL_VALID(em_hdr->flags)) if (!TCF_EM_REL_VALID(em_hdr->flags))
goto errout; goto errout;
......
...@@ -1661,9 +1661,11 @@ static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg) ...@@ -1661,9 +1661,11 @@ static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
struct tcf_bind_args *a = (void *)arg; struct tcf_bind_args *a = (void *)arg;
if (tp->ops->bind_class) { if (tp->ops->bind_class) {
tcf_tree_lock(tp); struct Qdisc *q = tcf_block_q(tp->chain->block);
sch_tree_lock(q);
tp->ops->bind_class(n, a->classid, a->cl); tp->ops->bind_class(n, a->classid, a->cl);
tcf_tree_unlock(tp); sch_tree_unlock(q);
} }
return 0; return 0;
} }
......
...@@ -281,7 +281,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, ...@@ -281,7 +281,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
goto err_out; goto err_out;
} }
error = tcf_block_get(&flow->block, &flow->filter_list); error = tcf_block_get(&flow->block, &flow->filter_list, sch);
if (error) { if (error) {
kfree(flow); kfree(flow);
goto err_out; goto err_out;
...@@ -546,7 +546,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -546,7 +546,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
p->link.q = &noop_qdisc; p->link.q = &noop_qdisc;
pr_debug("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q); pr_debug("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q);
err = tcf_block_get(&p->link.block, &p->link.filter_list); err = tcf_block_get(&p->link.block, &p->link.filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -1566,7 +1566,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t ...@@ -1566,7 +1566,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
if (cl == NULL) if (cl == NULL)
goto failure; goto failure;
err = tcf_block_get(&cl->block, &cl->filter_list); err = tcf_block_get(&cl->block, &cl->filter_list, sch);
if (err) { if (err) {
kfree(cl); kfree(cl);
return err; return err;
......
...@@ -412,7 +412,7 @@ static int drr_init_qdisc(struct Qdisc *sch, struct nlattr *opt) ...@@ -412,7 +412,7 @@ static int drr_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
struct drr_sched *q = qdisc_priv(sch); struct drr_sched *q = qdisc_priv(sch);
int err; int err;
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
err = qdisc_class_hash_init(&q->clhash); err = qdisc_class_hash_init(&q->clhash);
......
...@@ -344,7 +344,7 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -344,7 +344,7 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt)
if (!opt) if (!opt)
goto errout; goto errout;
err = tcf_block_get(&p->block, &p->filter_list); err = tcf_block_get(&p->block, &p->filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -481,7 +481,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -481,7 +481,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)
return err; return err;
} }
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -1033,7 +1033,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, ...@@ -1033,7 +1033,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (cl == NULL) if (cl == NULL)
return -ENOBUFS; return -ENOBUFS;
err = tcf_block_get(&cl->block, &cl->filter_list); err = tcf_block_get(&cl->block, &cl->filter_list, sch);
if (err) { if (err) {
kfree(cl); kfree(cl);
return err; return err;
...@@ -1405,7 +1405,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) ...@@ -1405,7 +1405,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
return err; return err;
q->eligible = RB_ROOT; q->eligible = RB_ROOT;
err = tcf_block_get(&q->root.block, &q->root.filter_list); err = tcf_block_get(&q->root.block, &q->root.filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -1030,7 +1030,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -1030,7 +1030,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
if (!opt) if (!opt)
return -EINVAL; return -EINVAL;
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
...@@ -1393,7 +1393,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, ...@@ -1393,7 +1393,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
if (!cl) if (!cl)
goto failure; goto failure;
err = tcf_block_get(&cl->block, &cl->filter_list); err = tcf_block_get(&cl->block, &cl->filter_list, sch);
if (err) { if (err) {
kfree(cl); kfree(cl);
goto failure; goto failure;
......
...@@ -59,7 +59,7 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -59,7 +59,7 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
int err; int err;
err = tcf_block_get(&q->block, &dev->ingress_cl_list); err = tcf_block_get(&q->block, &dev->ingress_cl_list, sch);
if (err) if (err)
return err; return err;
...@@ -153,11 +153,11 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -153,11 +153,11 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
int err; int err;
err = tcf_block_get(&q->ingress_block, &dev->ingress_cl_list); err = tcf_block_get(&q->ingress_block, &dev->ingress_cl_list, sch);
if (err) if (err)
return err; return err;
err = tcf_block_get(&q->egress_block, &dev->egress_cl_list); err = tcf_block_get(&q->egress_block, &dev->egress_cl_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -245,7 +245,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -245,7 +245,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
if (opt == NULL) if (opt == NULL)
return -EINVAL; return -EINVAL;
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -212,7 +212,7 @@ static int prio_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -212,7 +212,7 @@ static int prio_init(struct Qdisc *sch, struct nlattr *opt)
if (!opt) if (!opt)
return -EINVAL; return -EINVAL;
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -1419,7 +1419,7 @@ static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt) ...@@ -1419,7 +1419,7 @@ static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
int i, j, err; int i, j, err;
u32 max_cl_shift, maxbudg_shift, max_classes; u32 max_cl_shift, maxbudg_shift, max_classes;
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -553,7 +553,7 @@ static int sfb_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -553,7 +553,7 @@ static int sfb_init(struct Qdisc *sch, struct nlattr *opt)
struct sfb_sched_data *q = qdisc_priv(sch); struct sfb_sched_data *q = qdisc_priv(sch);
int err; int err;
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
......
...@@ -725,7 +725,7 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -725,7 +725,7 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
setup_deferrable_timer(&q->perturb_timer, sfq_perturbation, setup_deferrable_timer(&q->perturb_timer, sfq_perturbation,
(unsigned long)sch); (unsigned long)sch);
err = tcf_block_get(&q->block, &q->filter_list); err = tcf_block_get(&q->block, &q->filter_list, sch);
if (err) if (err)
return err; return err;
......
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