projects
/
powerpc.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge ../linus
[powerpc.git]
/
net
/
sched
/
sch_generic.c
diff --git
a/net/sched/sch_generic.c
b/net/sched/sch_generic.c
index
d7aca8e
..
74d4a1d
100644
(file)
--- a/
net/sched/sch_generic.c
+++ b/
net/sched/sch_generic.c
@@
-96,8
+96,11
@@
static inline int qdisc_restart(struct net_device *dev)
struct sk_buff *skb;
/* Dequeue packet */
struct sk_buff *skb;
/* Dequeue packet */
- if ((
skb = q->dequeue(q)) != NULL
) {
+ if ((
(skb = dev->gso_skb)) || ((skb = q->dequeue(q)))
) {
unsigned nolock = (dev->features & NETIF_F_LLTX);
unsigned nolock = (dev->features & NETIF_F_LLTX);
+
+ dev->gso_skb = NULL;
+
/*
* When the driver has LLTX set it does its own locking
* in start_xmit. No need to add additional overhead by
/*
* When the driver has LLTX set it does its own locking
* in start_xmit. No need to add additional overhead by
@@
-134,10
+137,8
@@
static inline int qdisc_restart(struct net_device *dev)
if (!netif_queue_stopped(dev)) {
int ret;
if (!netif_queue_stopped(dev)) {
int ret;
- if (netdev_nit)
- dev_queue_xmit_nit(skb, dev);
- ret = dev
->
hard_start_xmit(skb, dev);
+ ret = dev
_
hard_start_xmit(skb, dev);
if (ret == NETDEV_TX_OK) {
if (!nolock) {
netif_tx_unlock(dev);
if (ret == NETDEV_TX_OK) {
if (!nolock) {
netif_tx_unlock(dev);
@@
-171,7
+172,10
@@
static inline int qdisc_restart(struct net_device *dev)
*/
requeue:
*/
requeue:
- q->ops->requeue(skb, q);
+ if (skb->next)
+ dev->gso_skb = skb;
+ else
+ q->ops->requeue(skb, q);
netif_schedule(dev);
return 1;
}
netif_schedule(dev);
return 1;
}
@@
-181,9
+185,13
@@
requeue:
void __qdisc_run(struct net_device *dev)
{
void __qdisc_run(struct net_device *dev)
{
+ if (unlikely(dev->qdisc == &noop_qdisc))
+ goto out;
+
while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
/* NOTHING */;
while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
/* NOTHING */;
+out:
clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
}
clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
}
@@
-583,10
+591,17
@@
void dev_deactivate(struct net_device *dev)
dev_watchdog_down(dev);
dev_watchdog_down(dev);
- while (test_bit(__LINK_STATE_SCHED, &dev->state))
+ /* Wait for outstanding dev_queue_xmit calls. */
+ synchronize_rcu();
+
+ /* Wait for outstanding qdisc_run calls. */
+ while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
yield();
yield();
- spin_unlock_wait(&dev->_xmit_lock);
+ if (dev->gso_skb) {
+ kfree_skb(dev->gso_skb);
+ dev->gso_skb = NULL;
+ }
}
void dev_init_scheduler(struct net_device *dev)
}
void dev_init_scheduler(struct net_device *dev)