Skip to content

Commit

Permalink
pkt_sched: Move gso_skb into Qdisc.
Browse files Browse the repository at this point in the history
We liberate any dangling gso_skb during qdisc destruction.

It really only matters for the root qdisc.  But when qdiscs
can be shared by multiple netdev_queue objects, we can't
have the gso_skb in the netdev_queue any more.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 18, 2008
1 parent b4c2163 commit d3b753d
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 11 deletions.
1 change: 0 additions & 1 deletion include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ struct netdev_queue {
struct net_device *dev;
struct Qdisc *qdisc;
unsigned long state;
struct sk_buff *gso_skb;
spinlock_t _xmit_lock;
int xmit_lock_owner;
struct Qdisc *qdisc_sleeping;
Expand Down
1 change: 1 addition & 0 deletions include/net/sch_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct Qdisc
u32 handle;
u32 parent;
atomic_t refcnt;
struct sk_buff *gso_skb;
struct sk_buff_head q;
struct netdev_queue *dev_queue;
struct list_head list;
Expand Down
19 changes: 9 additions & 10 deletions net/sched/sch_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,20 @@ static inline int dev_requeue_skb(struct sk_buff *skb,
struct Qdisc *q)
{
if (unlikely(skb->next))
dev_queue->gso_skb = skb;
q->gso_skb = skb;
else
q->ops->requeue(skb, q);

netif_schedule_queue(dev_queue);
return 0;
}

static inline struct sk_buff *dequeue_skb(struct netdev_queue *dev_queue,
struct Qdisc *q)
static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
{
struct sk_buff *skb;

if ((skb = dev_queue->gso_skb))
dev_queue->gso_skb = NULL;
if ((skb = q->gso_skb))
q->gso_skb = NULL;
else
skb = q->dequeue(q);

Expand Down Expand Up @@ -155,10 +154,9 @@ static inline int qdisc_restart(struct netdev_queue *txq)
struct sk_buff *skb;

/* Dequeue packet */
if (unlikely((skb = dequeue_skb(txq, q)) == NULL))
if (unlikely((skb = dequeue_skb(q)) == NULL))
return 0;


/* And release queue */
spin_unlock(&txq->lock);

Expand Down Expand Up @@ -643,18 +641,19 @@ static void dev_deactivate_queue(struct net_device *dev,
void *_qdisc_default)
{
struct Qdisc *qdisc_default = _qdisc_default;
struct sk_buff *skb = NULL;
struct Qdisc *qdisc;
struct sk_buff *skb;

spin_lock_bh(&dev_queue->lock);

qdisc = dev_queue->qdisc;
if (qdisc) {
dev_queue->qdisc = qdisc_default;
qdisc_reset(qdisc);

skb = qdisc->gso_skb;
qdisc->gso_skb = NULL;
}
skb = dev_queue->gso_skb;
dev_queue->gso_skb = NULL;

spin_unlock_bh(&dev_queue->lock);

Expand Down

0 comments on commit d3b753d

Please sign in to comment.