aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2004-07-28 04:45:36 -0700
committerDavid S. Miller <davem@nuts.davemloft.net>2004-07-28 04:45:36 -0700
commit27f9a00a0e6fc565f5f52570ed633b599f89802f (patch)
tree298a105020ae4c9d594c1b0d9da512a5be3fa899 /net
parent6f7e7e9e21979e675c5e623a9217a38fbd8b6049 (diff)
downloadhistory-27f9a00a0e6fc565f5f52570ed633b599f89802f.tar.gz
[PKT_SCHED]: de-inline qdiscipline locking functions
This qdisc code has several inline functions for locking that is only used when adding/deleting queuing disciplines; so make them functions instead. The new qdisc_lock_tree encapsulates the locking used throughout this code. Also qdisc_run() is only called from net/core/dev.c so it should be defined there. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c7
-rw-r--r--net/sched/cls_api.c29
-rw-r--r--net/sched/sch_api.c11
-rw-r--r--net/sched/sch_generic.c27
4 files changed, 51 insertions, 23 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 381cd85a4c206a..af4654d93fb3bc 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1320,6 +1320,13 @@ int __skb_linearize(struct sk_buff *skb, int gfp_mask)
} \
}
+static inline void qdisc_run(struct net_device *dev)
+{
+ while (!netif_queue_stopped(dev) &&
+ qdisc_restart(dev)<0)
+ /* NOTHING */;
+}
+
/**
* dev_queue_xmit - transmit a buffer
* @skb: buffer to transmit
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 5d034cc0d874a6..9026a9ec9135de 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -236,12 +236,12 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
kfree(tp);
goto errout;
}
- write_lock(&qdisc_tree_lock);
- spin_lock_bh(&dev->queue_lock);
+
+ qdisc_lock_tree(dev);
tp->next = *back;
*back = tp;
- spin_unlock_bh(&dev->queue_lock);
- write_unlock(&qdisc_tree_lock);
+ qdisc_unlock_tree(dev);
+
} else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind))
goto errout;
@@ -249,11 +249,10 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
if (fh == 0) {
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
- write_lock(&qdisc_tree_lock);
- spin_lock_bh(&dev->queue_lock);
+ qdisc_lock_tree(dev);
*back = tp->next;
- spin_unlock_bh(&dev->queue_lock);
- write_unlock(&qdisc_tree_lock);
+ qdisc_unlock_tree(dev);
+
tfilter_notify(skb, n, tp, fh_s, RTM_DELTFILTER);
tcf_destroy(tp);
err = 0;
@@ -294,6 +293,19 @@ errout:
return err;
}
+unsigned long tcf_set_class(struct tcf_proto *tp, unsigned long *clp,
+ unsigned long cl)
+{
+ unsigned long old_cl;
+
+ tcf_tree_lock(tp);
+ old_cl = __cls_set_class(clp, cl);
+ tcf_tree_unlock(tp);
+
+ return old_cl;
+}
+
+
static int
tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
u32 pid, u32 seq, unsigned flags, int event)
@@ -459,3 +471,4 @@ subsys_initcall(tc_filter_init);
EXPORT_SYMBOL(register_tcf_proto_ops);
EXPORT_SYMBOL(unregister_tcf_proto_ops);
+EXPORT_SYMBOL(tcf_set_class);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 1ce72ab7a68964..6498c34c54947b 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -306,8 +306,7 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc)
if (dev->flags & IFF_UP)
dev_deactivate(dev);
- write_lock(&qdisc_tree_lock);
- spin_lock_bh(&dev->queue_lock);
+ qdisc_lock_tree(dev);
if (qdisc && qdisc->flags&TCQ_F_INGRES) {
oqdisc = dev->qdisc_ingress;
/* Prune old scheduler */
@@ -334,8 +333,7 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc)
dev->qdisc = &noop_qdisc;
}
- spin_unlock_bh(&dev->queue_lock);
- write_unlock(&qdisc_tree_lock);
+ qdisc_unlock_tree(dev);
if (dev->flags & IFF_UP)
dev_activate(dev);
@@ -454,10 +452,11 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
* before we set a netdevice's qdisc pointer to sch */
smp_wmb();
if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
- write_lock(&qdisc_tree_lock);
+ qdisc_lock_tree(dev);
sch->next = dev->qdisc_list;
dev->qdisc_list = sch;
- write_unlock(&qdisc_tree_lock);
+ qdisc_unlock_tree(dev);
+
#ifdef CONFIG_NET_ESTIMATOR
if (tca[TCA_RATE-1])
qdisc_new_estimator(&sch->stats, sch->stats_lock,
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 672650c572aaf0..ece985b6dc25eb 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -54,6 +54,18 @@
*/
rwlock_t qdisc_tree_lock = RW_LOCK_UNLOCKED;
+void qdisc_lock_tree(struct net_device *dev)
+{
+ write_lock(&qdisc_tree_lock);
+ spin_lock_bh(&dev->queue_lock);
+}
+
+void qdisc_unlock_tree(struct net_device *dev)
+{
+ spin_unlock_bh(&dev->queue_lock);
+ write_unlock(&qdisc_tree_lock);
+}
+
/*
dev->queue_lock serializes queue accesses for this device
AND dev->qdisc pointer itself.
@@ -513,13 +525,11 @@ void dev_deactivate(struct net_device *dev)
void dev_init_scheduler(struct net_device *dev)
{
- write_lock(&qdisc_tree_lock);
- spin_lock_bh(&dev->queue_lock);
+ qdisc_lock_tree(dev);
dev->qdisc = &noop_qdisc;
- spin_unlock_bh(&dev->queue_lock);
dev->qdisc_sleeping = &noop_qdisc;
dev->qdisc_list = NULL;
- write_unlock(&qdisc_tree_lock);
+ qdisc_unlock_tree(dev);
dev_watchdog_init(dev);
}
@@ -528,8 +538,7 @@ void dev_shutdown(struct net_device *dev)
{
struct Qdisc *qdisc;
- write_lock(&qdisc_tree_lock);
- spin_lock_bh(&dev->queue_lock);
+ qdisc_lock_tree(dev);
qdisc = dev->qdisc_sleeping;
dev->qdisc = &noop_qdisc;
dev->qdisc_sleeping = &noop_qdisc;
@@ -543,8 +552,7 @@ void dev_shutdown(struct net_device *dev)
BUG_TRAP(dev->qdisc_list == NULL);
BUG_TRAP(!timer_pending(&dev->watchdog_timer));
dev->qdisc_list = NULL;
- spin_unlock_bh(&dev->queue_lock);
- write_unlock(&qdisc_tree_lock);
+ qdisc_unlock_tree(dev);
}
EXPORT_SYMBOL(__netdev_watchdog_up);
@@ -554,4 +562,5 @@ EXPORT_SYMBOL(qdisc_create_dflt);
EXPORT_SYMBOL(qdisc_destroy);
EXPORT_SYMBOL(qdisc_reset);
EXPORT_SYMBOL(qdisc_restart);
-EXPORT_SYMBOL(qdisc_tree_lock);
+EXPORT_SYMBOL(qdisc_lock_tree);
+EXPORT_SYMBOL(qdisc_unlock_tree);