Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Linux: Kernel

[PATCH 1/5] netpoll: use sk_buff_head for txq

 

 

Linux kernel RSS feed   Index | Next | Previous | View Threaded


shemminger at osdl

Oct 23, 2006, 12:02 PM

Post #1 of 4 (370 views)
Permalink
[PATCH 1/5] netpoll: use sk_buff_head for txq

This is the 3rd version of the netpoll patches. The first patch
switches from open-coded skb list to using a skb_buff_head.
It also flushes packets from queue when device is removed from
netpoll.

Signed-off-by: Stephen Hemminger <shemminger [at] osdl>

--- netpoll.orig/net/core/netpoll.c
+++ netpoll/net/core/netpoll.c
@@ -37,10 +37,7 @@
#define MAX_RETRIES 20000

static struct sk_buff_head netpoll_pool;
-
-static DEFINE_SPINLOCK(queue_lock);
-static int queue_depth;
-static struct sk_buff *queue_head, *queue_tail;
+static struct sk_buff_head netpoll_txq;

static atomic_t trapped;

@@ -56,44 +53,35 @@ static void arp_reply(struct sk_buff *sk

static void queue_process(void *p)
{
- unsigned long flags;
struct sk_buff *skb;

- while (queue_head) {
- spin_lock_irqsave(&queue_lock, flags);
-
- skb = queue_head;
- queue_head = skb->next;
- if (skb == queue_tail)
- queue_head = NULL;
+ while ((skb = skb_dequeue(&netpoll_txq)))
+ dev_queue_xmit(skb);

- queue_depth--;
+}

- spin_unlock_irqrestore(&queue_lock, flags);
+static void queue_purge(struct net_device *dev)
+{
+ struct sk_buff *skb, *next;
+ unsigned long flags;

- dev_queue_xmit(skb);
+ spin_lock_irqsave(&netpoll_txq.lock, flags);
+ for (skb = (struct sk_buff *)netpoll_txq.next;
+ skb != (struct sk_buff *)&netpoll_txq; skb = next) {
+ next = skb->next;
+ if (skb->dev == dev) {
+ skb_unlink(skb, &netpoll_txq);
+ kfree_skb(skb);
+ }
}
+ spin_unlock_irqrestore(&netpoll_txq.lock, flags);
}

static DECLARE_WORK(send_queue, queue_process, NULL);

void netpoll_queue(struct sk_buff *skb)
{
- unsigned long flags;
-
- if (queue_depth == MAX_QUEUE_DEPTH) {
- __kfree_skb(skb);
- return;
- }
-
- spin_lock_irqsave(&queue_lock, flags);
- if (!queue_head)
- queue_head = skb;
- else
- queue_tail->next = skb;
- queue_tail = skb;
- queue_depth++;
- spin_unlock_irqrestore(&queue_lock, flags);
+ skb_queue_tail(&netpoll_txq, skb);

schedule_work(&send_queue);
}
@@ -745,6 +733,7 @@ int netpoll_setup(struct netpoll *np)
}

static int __init netpoll_init(void) {
+ skb_queue_head_init(&netpoll_txq);
skb_queue_head_init(&netpoll_pool);
return 0;
}
@@ -752,20 +741,22 @@ core_initcall(netpoll_init);

void netpoll_cleanup(struct netpoll *np)
{
- struct netpoll_info *npinfo;
+ struct net_device *dev = np->dev;
unsigned long flags;

- if (np->dev) {
- npinfo = np->dev->npinfo;
+ if (dev) {
+ struct netpoll_info *npinfo = dev->npinfo;
+
if (npinfo && npinfo->rx_np == np) {
spin_lock_irqsave(&npinfo->rx_lock, flags);
npinfo->rx_np = NULL;
npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
}
- dev_put(np->dev);
- }
+ dev_put(dev);

+ queue_purge(dev);
+ }
np->dev = NULL;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


davem at davemloft

Oct 23, 2006, 11:03 PM

Post #2 of 4 (349 views)
Permalink
Re: [PATCH 1/5] netpoll: use sk_buff_head for txq [In reply to]

From: Stephen Hemminger <shemminger [at] osdl>
Date: Mon, 23 Oct 2006 12:02:53 -0700

> + spin_lock_irqsave(&netpoll_txq.lock, flags);
> + for (skb = (struct sk_buff *)netpoll_txq.next;
> + skb != (struct sk_buff *)&netpoll_txq; skb = next) {
> + next = skb->next;
> + if (skb->dev == dev) {
> + skb_unlink(skb, &netpoll_txq);
> + kfree_skb(skb);
> + }
> }
> + spin_unlock_irqrestore(&netpoll_txq.lock, flags);

IRQ's are disabled, I think we can't call kfree_skb() in such a
context.

That's why zap_completion_queue() has all of these funny
skb->destructor checks and such, all of this stuff potentially runs in
IRQ context.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


shemminger at osdl

Oct 24, 2006, 7:14 AM

Post #3 of 4 (338 views)
Permalink
Re: [PATCH 1/5] netpoll: use sk_buff_head for txq [In reply to]

On Tue, 24 Oct 2006 07:51:30 -0700
Stephen Hemminger <shemminger [at] osdl> wrote:

> On Mon, 23 Oct 2006 23:03:50 -0700 (PDT)
> David Miller <davem [at] davemloft> wrote:
>
> > From: Stephen Hemminger <shemminger [at] osdl>
> > Date: Mon, 23 Oct 2006 12:02:53 -0700
> >
> > > + spin_lock_irqsave(&netpoll_txq.lock, flags);
> > > + for (skb = (struct sk_buff *)netpoll_txq.next;
> > > + skb != (struct sk_buff *)&netpoll_txq; skb = next) {
> > > + next = skb->next;
> > > + if (skb->dev == dev) {
> > > + skb_unlink(skb, &netpoll_txq);
> > > + kfree_skb(skb);
> > > + }
> > > }
> > > + spin_unlock_irqrestore(&netpoll_txq.lock, flags);
> >
> > IRQ's are disabled, I think we can't call kfree_skb() in such a
> > context.
>
> It is save since the skb's only come from this code (no destructors).
>
Actually it does use destructors... I am doing a better version (per-device).
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


shemminger at osdl

Oct 24, 2006, 7:51 AM

Post #4 of 4 (345 views)
Permalink
Re: [PATCH 1/5] netpoll: use sk_buff_head for txq [In reply to]

On Mon, 23 Oct 2006 23:03:50 -0700 (PDT)
David Miller <davem [at] davemloft> wrote:

> From: Stephen Hemminger <shemminger [at] osdl>
> Date: Mon, 23 Oct 2006 12:02:53 -0700
>
> > + spin_lock_irqsave(&netpoll_txq.lock, flags);
> > + for (skb = (struct sk_buff *)netpoll_txq.next;
> > + skb != (struct sk_buff *)&netpoll_txq; skb = next) {
> > + next = skb->next;
> > + if (skb->dev == dev) {
> > + skb_unlink(skb, &netpoll_txq);
> > + kfree_skb(skb);
> > + }
> > }
> > + spin_unlock_irqrestore(&netpoll_txq.lock, flags);
>
> IRQ's are disabled, I think we can't call kfree_skb() in such a
> context.

It is save since the skb's only come from this code (no destructors).

>
> That's why zap_completion_queue() has all of these funny
> skb->destructor checks and such, all of this stuff potentially runs in
> IRQ context.

It should use __kfree_skb in the purge routine (like other places).
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Linux kernel RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.