tree 2fd51ff3b7097eb3ffc41ea3a1d8b3ba04715b4c
parent 6869c4d8e066e21623c812c448a05f1ed931c9c6
author David S. Miller <[EMAIL PROTECTED]> Wed, 10 Aug 2005 09:25:21 -0700
committer David S. Miller <[EMAIL PROTECTED]> Tue, 30 Aug 2005 05:31:14 -0700

[NET]: Kill skb->list

Remove the "list" member of struct sk_buff, as it is entirely
redundant.  All SKB list removal callers know which list the
SKB is on, so storing this in sk_buff does nothing other than
taking up some space.

Two tricky bits were SCTP, which I took care of, and two ATM
drivers which Francois Romieu <[EMAIL PROTECTED]> fixed
up.

Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
Signed-off-by: Francois Romieu <[EMAIL PROTECTED]>

 drivers/atm/nicstar.c            |  157 ++++++++++++++++++---------------------
 drivers/atm/nicstar.h            |   16 +++
 drivers/atm/zatm.c               |    8 +
 drivers/bluetooth/bfusb.c        |    8 -
 drivers/ieee1394/ieee1394_core.c |    4 
 drivers/isdn/act2000/capi.c      |    2 
 drivers/net/shaper.c             |   50 ------------
 drivers/net/wan/sdla_fr.c        |   22 +----
 drivers/usb/net/usbnet.c         |   21 ++---
 include/linux/skbuff.h           |   16 +--
 net/atm/ipcommon.c               |    3 
 net/ax25/ax25_subr.c             |    2 
 net/core/skbuff.c                |   57 +++++---------
 net/decnet/af_decnet.c           |    2 
 net/decnet/dn_nsp_out.c          |    2 
 net/econet/af_econet.c           |    4 
 net/ipv4/tcp.c                   |    2 
 net/ipv4/tcp_input.c             |   29 +++----
 net/ipv4/tcp_output.c            |    6 -
 net/irda/irlap_frame.c           |    6 -
 net/lapb/lapb_subr.c             |    2 
 net/llc/af_llc.c                 |    2 
 net/llc/llc_conn.c               |    6 +
 net/netrom/nr_subr.c             |    2 
 net/rose/rose_subr.c             |    2 
 net/sctp/socket.c                |    4 
 net/sctp/ulpqueue.c              |   63 +++++++++------
 net/unix/garbage.c               |   12 +-
 net/x25/x25_subr.c               |    2 
 29 files changed, 229 insertions(+), 283 deletions(-)

diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -214,8 +214,7 @@ static int __devinit ns_init_card(int i,
 static void __devinit ns_init_card_error(ns_dev *card, int error);
 static scq_info *get_scq(int size, u32 scd);
 static void free_scq(scq_info *scq, struct atm_vcc *vcc);
-static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
-                       u32 handle2, u32 addr2);
+static void push_rxbufs(ns_dev *, struct sk_buff *);
 static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
 static int ns_open(struct atm_vcc *vcc);
 static void ns_close(struct atm_vcc *vcc);
@@ -766,6 +765,7 @@ static int __devinit ns_init_card(int i,
          ns_init_card_error(card, error);
         return error;
       }
+      NS_SKB_CB(hb)->buf_type = BUF_NONE;
       skb_queue_tail(&card->hbpool.queue, hb);
       card->hbpool.count++;
    }
@@ -786,9 +786,10 @@ static int __devinit ns_init_card(int i,
          ns_init_card_error(card, error);
         return error;
       }
+      NS_SKB_CB(lb)->buf_type = BUF_LG;
       skb_queue_tail(&card->lbpool.queue, lb);
       skb_reserve(lb, NS_SMBUFSIZE);
-      push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0);
+      push_rxbufs(card, lb);
       /* Due to the implementation of push_rxbufs() this is 1, not 0 */
       if (j == 1)
       {
@@ -822,9 +823,10 @@ static int __devinit ns_init_card(int i,
          ns_init_card_error(card, error);
         return error;
       }
+      NS_SKB_CB(sb)->buf_type = BUF_SM;
       skb_queue_tail(&card->sbpool.queue, sb);
       skb_reserve(sb, NS_AAL0_HEADER);
-      push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0);
+      push_rxbufs(card, sb);
    }
    /* Test for strange behaviour which leads to crashes */
    if ((bcount = ns_stat_sfbqc_get(readl(card->membase + STAT))) < 
card->sbnr.min)
@@ -852,6 +854,7 @@ static int __devinit ns_init_card(int i,
          ns_init_card_error(card, error);
         return error;
       }
+      NS_SKB_CB(iovb)->buf_type = BUF_NONE;
       skb_queue_tail(&card->iovpool.queue, iovb);
       card->iovpool.count++;
    }
@@ -1078,12 +1081,18 @@ static void free_scq(scq_info *scq, stru
 
 /* The handles passed must be pointers to the sk_buff containing the small
    or large buffer(s) cast to u32. */
-static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
-                       u32 handle2, u32 addr2)
+static void push_rxbufs(ns_dev *card, struct sk_buff *skb)
 {
+   struct ns_skb_cb *cb = NS_SKB_CB(skb);
+   u32 handle1, addr1;
+   u32 handle2, addr2;
    u32 stat;
    unsigned long flags;
    
+   /* *BARF* */
+   handle2 = addr2 = 0;
+   handle1 = (u32)skb;
+   addr1 = (u32)virt_to_bus(skb->data);
 
 #ifdef GENERAL_DEBUG
    if (!addr1)
@@ -1093,7 +1102,7 @@ static void push_rxbufs(ns_dev *card, u3
    stat = readl(card->membase + STAT);
    card->sbfqc = ns_stat_sfbqc_get(stat);
    card->lbfqc = ns_stat_lfbqc_get(stat);
-   if (type == BUF_SM)
+   if (cb->buf_type == BUF_SM)
    {
       if (!addr2)
       {
@@ -1111,7 +1120,7 @@ static void push_rxbufs(ns_dev *card, u3
         }
       }      
    }
-   else /* type == BUF_LG */
+   else /* buf_type == BUF_LG */
    {
       if (!addr2)
       {
@@ -1132,26 +1141,26 @@ static void push_rxbufs(ns_dev *card, u3
 
    if (addr2)
    {
-      if (type == BUF_SM)
+      if (cb->buf_type == BUF_SM)
       {
          if (card->sbfqc >= card->sbnr.max)
          {
-            skb_unlink((struct sk_buff *) handle1);
+            skb_unlink((struct sk_buff *) handle1, &card->sbpool.queue);
             dev_kfree_skb_any((struct sk_buff *) handle1);
-            skb_unlink((struct sk_buff *) handle2);
+            skb_unlink((struct sk_buff *) handle2, &card->sbpool.queue);
             dev_kfree_skb_any((struct sk_buff *) handle2);
             return;
          }
         else
             card->sbfqc += 2;
       }
-      else /* (type == BUF_LG) */
+      else /* (buf_type == BUF_LG) */
       {
          if (card->lbfqc >= card->lbnr.max)
          {
-            skb_unlink((struct sk_buff *) handle1);
+            skb_unlink((struct sk_buff *) handle1, &card->lbpool.queue);
             dev_kfree_skb_any((struct sk_buff *) handle1);
-            skb_unlink((struct sk_buff *) handle2);
+            skb_unlink((struct sk_buff *) handle2, &card->lbpool.queue);
             dev_kfree_skb_any((struct sk_buff *) handle2);
             return;
          }
@@ -1166,12 +1175,12 @@ static void push_rxbufs(ns_dev *card, u3
       writel(handle2, card->membase + DR2);
       writel(addr1, card->membase + DR1);
       writel(handle1, card->membase + DR0);
-      writel(NS_CMD_WRITE_FREEBUFQ | (u32) type, card->membase + CMD);
+      writel(NS_CMD_WRITE_FREEBUFQ | cb->buf_type, card->membase + CMD);
  
       spin_unlock_irqrestore(&card->res_lock, flags);
 
       XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n", card->index,
-              (type == BUF_SM ? "small" : "large"), addr1, addr2);
+              (cb->buf_type == BUF_SM ? "small" : "large"), addr1, addr2);
    }
 
    if (!card->efbie && card->sbfqc >= card->sbnr.min &&
@@ -1322,9 +1331,10 @@ static irqreturn_t ns_irq_handler(int ir
             card->efbie = 0;
             break;
          }
+         NS_SKB_CB(sb)->buf_type = BUF_SM;
          skb_queue_tail(&card->sbpool.queue, sb);
          skb_reserve(sb, NS_AAL0_HEADER);
-         push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 
0);
+         push_rxbufs(card, sb);
       }
       card->sbfqc = i;
       process_rsq(card);
@@ -1348,9 +1358,10 @@ static irqreturn_t ns_irq_handler(int ir
             card->efbie = 0;
             break;
          }
+         NS_SKB_CB(lb)->buf_type = BUF_LG;
          skb_queue_tail(&card->lbpool.queue, lb);
          skb_reserve(lb, NS_SMBUFSIZE);
-         push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 
0);
+         push_rxbufs(card, lb);
       }
       card->lbfqc = i;
       process_rsq(card);
@@ -2227,6 +2238,7 @@ static void dequeue_rx(ns_dev *card, ns_
             recycle_rx_buf(card, skb);
             return;
         }
+         NS_SKB_CB(iovb)->buf_type = BUF_NONE;
       }
       else
          if (--card->iovpool.count < card->iovnr.min)
@@ -2234,6 +2246,7 @@ static void dequeue_rx(ns_dev *card, ns_
            struct sk_buff *new_iovb;
            if ((new_iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL)
            {
+               NS_SKB_CB(iovb)->buf_type = BUF_NONE;
                skb_queue_tail(&card->iovpool.queue, new_iovb);
                card->iovpool.count++;
            }
@@ -2264,7 +2277,7 @@ static void dequeue_rx(ns_dev *card, ns_
 
    if (NS_SKB(iovb)->iovcnt == 1)
    {
-      if (skb->list != &card->sbpool.queue)
+      if (NS_SKB_CB(skb)->buf_type != BUF_SM)
       {
          printk("nicstar%d: Expected a small buffer, and this is not one.\n",
                card->index);
@@ -2278,7 +2291,7 @@ static void dequeue_rx(ns_dev *card, ns_
    }
    else /* NS_SKB(iovb)->iovcnt >= 2 */
    {
-      if (skb->list != &card->lbpool.queue)
+      if (NS_SKB_CB(skb)->buf_type != BUF_LG)
       {
          printk("nicstar%d: Expected a large buffer, and this is not one.\n",
                card->index);
@@ -2322,8 +2335,7 @@ static void dequeue_rx(ns_dev *card, ns_
          /* skb points to a small buffer */
          if (!atm_charge(vcc, skb->truesize))
          {
-            push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data),
-                        0, 0);
+            push_rxbufs(card, skb);
             atomic_inc(&vcc->stats->rx_drop);
          }
          else
@@ -2350,8 +2362,7 @@ static void dequeue_rx(ns_dev *card, ns_
         {
             if (!atm_charge(vcc, sb->truesize))
             {
-               push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data),
-                           0, 0);
+               push_rxbufs(card, sb);
                atomic_inc(&vcc->stats->rx_drop);
             }
             else
@@ -2367,16 +2378,14 @@ static void dequeue_rx(ns_dev *card, ns_
                atomic_inc(&vcc->stats->rx);
             }
 
-            push_rxbufs(card, BUF_LG, (u32) skb,
-                          (u32) virt_to_bus(skb->data), 0, 0);
+            push_rxbufs(card, skb);
 
         }
         else                   /* len > NS_SMBUFSIZE, the usual case */
         {
             if (!atm_charge(vcc, skb->truesize))
             {
-               push_rxbufs(card, BUF_LG, (u32) skb,
-                           (u32) virt_to_bus(skb->data), 0, 0);
+               push_rxbufs(card, skb);
                atomic_inc(&vcc->stats->rx_drop);
             }
             else
@@ -2394,8 +2403,7 @@ static void dequeue_rx(ns_dev *card, ns_
                atomic_inc(&vcc->stats->rx);
             }
 
-            push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data),
-                        0, 0);
+            push_rxbufs(card, sb);
 
          }
         
@@ -2430,6 +2438,7 @@ static void dequeue_rx(ns_dev *card, ns_
                   card->hbpool.count++;
                }
             }
+            NS_SKB_CB(hb)->buf_type = BUF_NONE;
         }
         else
          if (--card->hbpool.count < card->hbnr.min)
@@ -2437,6 +2446,7 @@ static void dequeue_rx(ns_dev *card, ns_
             struct sk_buff *new_hb;
             if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL)
             {
+               NS_SKB_CB(new_hb)->buf_type = BUF_NONE;
                skb_queue_tail(&card->hbpool.queue, new_hb);
                card->hbpool.count++;
             }
@@ -2444,6 +2454,7 @@ static void dequeue_rx(ns_dev *card, ns_
            {
                if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL)
                {
+                  NS_SKB_CB(new_hb)->buf_type = BUF_NONE;
                   skb_queue_tail(&card->hbpool.queue, new_hb);
                   card->hbpool.count++;
                }
@@ -2473,8 +2484,7 @@ static void dequeue_rx(ns_dev *card, ns_
             remaining = len - iov->iov_len;
             iov++;
             /* Free the small buffer */
-            push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data),
-                        0, 0);
+            push_rxbufs(card, sb);
 
             /* Copy all large buffers to the huge buffer and free them */
             for (j = 1; j < NS_SKB(iovb)->iovcnt; j++)
@@ -2485,8 +2495,7 @@ static void dequeue_rx(ns_dev *card, ns_
                skb_put(hb, tocopy);
                iov++;
                remaining -= tocopy;
-               push_rxbufs(card, BUF_LG, (u32) lb,
-                           (u32) virt_to_bus(lb->data), 0, 0);
+               push_rxbufs(card, lb);
             }
 #ifdef EXTRA_DEBUG
             if (remaining != 0 || hb->len != len)
@@ -2527,9 +2536,10 @@ static void ns_sb_destructor(struct sk_b
       sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
       if (sb == NULL)
          break;
+      NS_SKB_CB(sb)->buf_type = BUF_SM;
       skb_queue_tail(&card->sbpool.queue, sb);
       skb_reserve(sb, NS_AAL0_HEADER);
-      push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0);
+      push_rxbufs(card, sb);
    } while (card->sbfqc < card->sbnr.min);
 }
 
@@ -2550,9 +2560,10 @@ static void ns_lb_destructor(struct sk_b
       lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
       if (lb == NULL)
          break;
+      NS_SKB_CB(lb)->buf_type = BUF_LG;
       skb_queue_tail(&card->lbpool.queue, lb);
       skb_reserve(lb, NS_SMBUFSIZE);
-      push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0);
+      push_rxbufs(card, lb);
    } while (card->lbfqc < card->lbnr.min);
 }
 
@@ -2569,6 +2580,7 @@ static void ns_hb_destructor(struct sk_b
       hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
       if (hb == NULL)
          break;
+      NS_SKB_CB(hb)->buf_type = BUF_NONE;
       skb_queue_tail(&card->hbpool.queue, hb);
       card->hbpool.count++;
    }
@@ -2577,45 +2589,25 @@ static void ns_hb_destructor(struct sk_b
 #endif /* NS_USE_DESTRUCTORS */
 
 
-
 static void recycle_rx_buf(ns_dev *card, struct sk_buff *skb)
 {
-   if (skb->list == &card->sbpool.queue)
-      push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data), 0, 0);
-   else if (skb->list == &card->lbpool.queue)
-      push_rxbufs(card, BUF_LG, (u32) skb, (u32) virt_to_bus(skb->data), 0, 0);
-   else
-   {
-      printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
-      dev_kfree_skb_any(skb);
-   }
-}
+       struct ns_skb_cb *cb = NS_SKB_CB(skb);
 
+       if (unlikely(cb->buf_type == BUF_NONE)) {
+               printk("nicstar%d: What kind of rx buffer is this?\n", 
card->index);
+               dev_kfree_skb_any(skb);
+       } else
+               push_rxbufs(card, skb);
+}
 
 
 static void recycle_iovec_rx_bufs(ns_dev *card, struct iovec *iov, int count)
 {
-   struct sk_buff *skb;
-
-   for (; count > 0; count--)
-   {
-      skb = (struct sk_buff *) (iov++)->iov_base;
-      if (skb->list == &card->sbpool.queue)
-         push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data),
-                    0, 0);
-      else if (skb->list == &card->lbpool.queue)
-         push_rxbufs(card, BUF_LG, (u32) skb, (u32) virt_to_bus(skb->data),
-                    0, 0);
-      else
-      {
-         printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
-         dev_kfree_skb_any(skb);
-      }
-   }
+       while (count-- > 0)
+               recycle_rx_buf(card, (struct sk_buff *) (iov++)->iov_base);
 }
 
 
-
 static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb)
 {
    if (card->iovpool.count < card->iovnr.max)
@@ -2631,7 +2623,7 @@ static void recycle_iov_buf(ns_dev *card
 
 static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
 {
-   skb_unlink(sb);
+   skb_unlink(sb, &card->sbpool.queue);
 #ifdef NS_USE_DESTRUCTORS
    if (card->sbfqc < card->sbnr.min)
 #else
@@ -2640,10 +2632,10 @@ static void dequeue_sm_buf(ns_dev *card,
       struct sk_buff *new_sb;
       if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL)
       {
+         NS_SKB_CB(new_sb)->buf_type = BUF_SM;
          skb_queue_tail(&card->sbpool.queue, new_sb);
          skb_reserve(new_sb, NS_AAL0_HEADER);
-         push_rxbufs(card, BUF_SM, (u32) new_sb,
-                     (u32) virt_to_bus(new_sb->data), 0, 0);
+         push_rxbufs(card, new_sb);
       }
    }
    if (card->sbfqc < card->sbnr.init)
@@ -2652,10 +2644,10 @@ static void dequeue_sm_buf(ns_dev *card,
       struct sk_buff *new_sb;
       if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL)
       {
+         NS_SKB_CB(new_sb)->buf_type = BUF_SM;
          skb_queue_tail(&card->sbpool.queue, new_sb);
          skb_reserve(new_sb, NS_AAL0_HEADER);
-         push_rxbufs(card, BUF_SM, (u32) new_sb,
-                     (u32) virt_to_bus(new_sb->data), 0, 0);
+         push_rxbufs(card, new_sb);
       }
    }
 }
@@ -2664,7 +2656,7 @@ static void dequeue_sm_buf(ns_dev *card,
 
 static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb)
 {
-   skb_unlink(lb);
+   skb_unlink(lb, &card->lbpool.queue);
 #ifdef NS_USE_DESTRUCTORS
    if (card->lbfqc < card->lbnr.min)
 #else
@@ -2673,10 +2665,10 @@ static void dequeue_lg_buf(ns_dev *card,
       struct sk_buff *new_lb;
       if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL)
       {
+         NS_SKB_CB(new_lb)->buf_type = BUF_LG;
          skb_queue_tail(&card->lbpool.queue, new_lb);
          skb_reserve(new_lb, NS_SMBUFSIZE);
-         push_rxbufs(card, BUF_LG, (u32) new_lb,
-                     (u32) virt_to_bus(new_lb->data), 0, 0);
+         push_rxbufs(card, new_lb);
       }
    }
    if (card->lbfqc < card->lbnr.init)
@@ -2685,10 +2677,10 @@ static void dequeue_lg_buf(ns_dev *card,
       struct sk_buff *new_lb;
       if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL)
       {
+         NS_SKB_CB(new_lb)->buf_type = BUF_LG;
          skb_queue_tail(&card->lbpool.queue, new_lb);
          skb_reserve(new_lb, NS_SMBUFSIZE);
-         push_rxbufs(card, BUF_LG, (u32) new_lb,
-                     (u32) virt_to_bus(new_lb->data), 0, 0);
+         push_rxbufs(card, new_lb);
       }
    }
 }
@@ -2880,9 +2872,10 @@ static int ns_ioctl(struct atm_dev *dev,
                   sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
                   if (sb == NULL)
                      return -ENOMEM;
+                  NS_SKB_CB(sb)->buf_type = BUF_SM;
                   skb_queue_tail(&card->sbpool.queue, sb);
                   skb_reserve(sb, NS_AAL0_HEADER);
-                  push_rxbufs(card, BUF_SM, (u32) sb, (u32) 
virt_to_bus(sb->data), 0, 0);
+                  push_rxbufs(card, sb);
               }
               break;
 
@@ -2894,9 +2887,10 @@ static int ns_ioctl(struct atm_dev *dev,
                   lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
                   if (lb == NULL)
                      return -ENOMEM;
+                  NS_SKB_CB(lb)->buf_type = BUF_LG;
                   skb_queue_tail(&card->lbpool.queue, lb);
                   skb_reserve(lb, NS_SMBUFSIZE);
-                  push_rxbufs(card, BUF_LG, (u32) lb, (u32) 
virt_to_bus(lb->data), 0, 0);
+                  push_rxbufs(card, lb);
               }
               break;
 
@@ -2923,6 +2917,7 @@ static int ns_ioctl(struct atm_dev *dev,
                   hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
                   if (hb == NULL)
                      return -ENOMEM;
+                  NS_SKB_CB(hb)->buf_type = BUF_NONE;
                   ns_grab_int_lock(card, flags);
                   skb_queue_tail(&card->hbpool.queue, hb);
                   card->hbpool.count++;
@@ -2953,6 +2948,7 @@ static int ns_ioctl(struct atm_dev *dev,
                   iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
                   if (iovb == NULL)
                      return -ENOMEM;
+                  NS_SKB_CB(iovb)->buf_type = BUF_NONE;
                   ns_grab_int_lock(card, flags);
                   skb_queue_tail(&card->iovpool.queue, iovb);
                   card->iovpool.count++;
@@ -2979,17 +2975,12 @@ static int ns_ioctl(struct atm_dev *dev,
 }
 
 
-
 static void which_list(ns_dev *card, struct sk_buff *skb)
 {
-   printk("It's a %s buffer.\n", skb->list == &card->sbpool.queue ?
-          "small" : skb->list == &card->lbpool.queue ? "large" :
-         skb->list == &card->hbpool.queue ? "huge" :
-         skb->list == &card->iovpool.queue ? "iovec" : "unknown");
+       printk("skb buf_type: 0x%08x\n", NS_SKB_CB(skb)->buf_type);
 }
 
 
-
 static void ns_poll(unsigned long arg)
 {
    int i;
diff --git a/drivers/atm/nicstar.h b/drivers/atm/nicstar.h
--- a/drivers/atm/nicstar.h
+++ b/drivers/atm/nicstar.h
@@ -103,8 +103,14 @@
 
 #define NS_IOREMAP_SIZE 4096
 
-#define BUF_SM 0x00000000      /* These two are used for push_rxbufs() */
-#define BUF_LG 0x00000001       /* CMD, Write_FreeBufQ, LBUF bit */
+/*
+ * BUF_XX distinguish the Rx buffers depending on their (small/large) size.
+ * BUG_SM and BUG_LG are both used by the driver and the device.
+ * BUF_NONE is only used by the driver.
+ */
+#define BUF_SM         0x00000000      /* These two are used for push_rxbufs() 
*/
+#define BUF_LG         0x00000001      /* CMD, Write_FreeBufQ, LBUF bit */
+#define BUF_NONE       0xffffffff      /* Software only: */
 
 #define NS_HBUFSIZE 65568      /* Size of max. AAL5 PDU */
 #define NS_MAX_IOVECS (2 + (65568 - NS_SMBUFSIZE) / \
@@ -684,6 +690,12 @@ enum ns_regs
 /* Device driver structures 
***************************************************/
 
 
+struct ns_skb_cb {
+       u32 buf_type;                   /* BUF_SM/BUF_LG/BUF_NONE */
+};
+
+#define NS_SKB_CB(skb) ((struct ns_skb_cb *)((skb)->cb))
+
 typedef struct tsq_info
 {
    void *org;
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -417,10 +417,12 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
                chan = (here[3] & uPD98401_AAL5_CHAN) >>
                    uPD98401_AAL5_CHAN_SHIFT;
                if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {
+                       int pos = ZATM_VCC(vcc)->pool;
+
                        vcc = zatm_dev->rx_map[chan];
-                       if (skb == zatm_dev->last_free[ZATM_VCC(vcc)->pool])
-                               zatm_dev->last_free[ZATM_VCC(vcc)->pool] = NULL;
-                       skb_unlink(skb);
+                       if (skb == zatm_dev->last_free[pos])
+                               zatm_dev->last_free[pos] = NULL;
+                       skb_unlink(skb, zatm_dev->pool + pos);
                }
                else {
                        printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -158,7 +158,7 @@ static int bfusb_send_bulk(struct bfusb 
        if (err) {
                BT_ERR("%s bulk tx submit failed urb %p err %d", 
                                        bfusb->hdev->name, urb, err);
-               skb_unlink(skb);
+               skb_unlink(skb, &bfusb->pending_q);
                usb_free_urb(urb);
        } else
                atomic_inc(&bfusb->pending_tx);
@@ -212,7 +212,7 @@ static void bfusb_tx_complete(struct urb
 
        read_lock(&bfusb->lock);
 
-       skb_unlink(skb);
+       skb_unlink(skb, &bfusb->pending_q);
        skb_queue_tail(&bfusb->completed_q, skb);
 
        bfusb_tx_wakeup(bfusb);
@@ -253,7 +253,7 @@ static int bfusb_rx_submit(struct bfusb 
        if (err) {
                BT_ERR("%s bulk rx submit failed urb %p err %d",
                                        bfusb->hdev->name, urb, err);
-               skb_unlink(skb);
+               skb_unlink(skb, &bfusb->pending_q);
                kfree_skb(skb);
                usb_free_urb(urb);
        }
@@ -398,7 +398,7 @@ static void bfusb_rx_complete(struct urb
                buf   += len;
        }
 
-       skb_unlink(skb);
+       skb_unlink(skb, &bfusb->pending_q);
        kfree_skb(skb);
 
        bfusb_rx_submit(bfusb, urb);
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -681,7 +681,7 @@ static void handle_packet_response(struc
                 return;
         }
 
-       __skb_unlink(skb, skb->list);
+       __skb_unlink(skb, &host->pending_packet_queue);
 
        if (packet->state == hpsb_queued) {
                packet->sendtime = jiffies;
@@ -989,7 +989,7 @@ void abort_timedouts(unsigned long __opa
                packet = (struct hpsb_packet *)skb->data;
 
                if (time_before(packet->sendtime + expire, jiffies)) {
-                       __skb_unlink(skb, skb->list);
+                       __skb_unlink(skb, &host->pending_packet_queue);
                        packet->state = hpsb_complete;
                        packet->ack_code = ACKX_TIMEOUT;
                        queue_packet_complete(packet);
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -606,7 +606,7 @@ handle_ack(act2000_card *card, act2000_c
                 if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == 
chan->ncci) &&
                    (m->msg.data_b3_req.blocknr == blocknr)) {
                        /* found corresponding DATA_B3_REQ */
-                        skb_unlink(tmp);
+                        skb_unlink(tmp, &card->ackq);
                        chan->queued -= m->msg.data_b3_req.datalen;
                        if (m->msg.data_b3_req.flags)
                                ret = m->msg.data_b3_req.datalen;
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -156,52 +156,6 @@ static int shaper_start_xmit(struct sk_b
         
        SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb);
        
-#ifdef SHAPER_COMPLEX /* and broken.. */
-
-       while(ptr && ptr!=(struct sk_buff *)&shaper->sendq)
-       {
-               if(ptr->pri<skb->pri 
-                       && jiffies - SHAPERCB(ptr)->shapeclock < SHAPER_MAXSLIP)
-               {
-                       struct sk_buff *tmp=ptr->prev;
-
-                       /*
-                        *      It goes before us therefore we slip the length
-                        *      of the new frame.
-                        */
-
-                       SHAPERCB(ptr)->shapeclock+=SHAPERCB(skb)->shapelen;
-                       SHAPERCB(ptr)->shapelatency+=SHAPERCB(skb)->shapelen;
-
-                       /*
-                        *      The packet may have slipped so far back it
-                        *      fell off.
-                        */
-                       if(SHAPERCB(ptr)->shapelatency > SHAPER_LATENCY)
-                       {
-                               skb_unlink(ptr);
-                               dev_kfree_skb(ptr);
-                       }
-                       ptr=tmp;
-               }
-               else
-                       break;
-       }
-       if(ptr==NULL || ptr==(struct sk_buff *)&shaper->sendq)
-               skb_queue_head(&shaper->sendq,skb);
-       else
-       {
-               struct sk_buff *tmp;
-               /*
-                *      Set the packet clock out time according to the
-                *      frames ahead. Im sure a bit of thought could drop
-                *      this loop.
-                */
-               for(tmp=skb_peek(&shaper->sendq); tmp!=NULL && tmp!=ptr; 
tmp=tmp->next)
-                       SHAPERCB(skb)->shapeclock+=tmp->shapelen;
-               skb_append(ptr,skb);
-       }
-#else
        {
                struct sk_buff *tmp;
                /*
@@ -220,7 +174,7 @@ static int shaper_start_xmit(struct sk_b
                } else
                        skb_queue_tail(&shaper->sendq, skb);
        }
-#endif         
+
        if(sh_debug)
                printk("Frame queued.\n");
        if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN)
@@ -302,7 +256,7 @@ static void shaper_kick(struct shaper *s
                         *      Pull the frame and get interrupts back on.
                         */
                         
-                       skb_unlink(skb);
+                       skb_unlink(skb, &shaper->sendq);
                        if (shaper->recovery < 
                            SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen)
                                shaper->recovery = SHAPERCB(skb)->shapeclock + 
SHAPERCB(skb)->shapelen;
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
--- a/drivers/net/wan/sdla_fr.c
+++ b/drivers/net/wan/sdla_fr.c
@@ -445,7 +445,7 @@ void        s508_s514_unlock(sdla_t *card, uns
 void   s508_s514_lock(sdla_t *card, unsigned long *smp_flags);
 
 unsigned short calc_checksum (char *, int);
-static int setup_fr_header(struct sk_buff** skb,
+static int setup_fr_header(struct sk_buff *skb,
                           struct net_device* dev, char op_mode);
 
 
@@ -1372,7 +1372,7 @@ static int if_send(struct sk_buff* skb, 
        /* Move the if_header() code to here. By inserting frame
         * relay header in if_header() we would break the
         * tcpdump and other packet sniffers */
-       chan->fr_header_len = setup_fr_header(&skb,dev,chan->common.usedby);
+       chan->fr_header_len = setup_fr_header(skb,dev,chan->common.usedby);
        if (chan->fr_header_len < 0 ){
                ++chan->ifstats.tx_dropped;
                ++card->wandev.stats.tx_dropped;
@@ -1597,8 +1597,6 @@ static int setup_for_delayed_transmit(st
                return 1;
        }
 
-       skb_unlink(skb);
-       
         chan->transmit_length = len;
        chan->delay_skb = skb;
         
@@ -4871,18 +4869,15 @@ static void unconfig_fr (sdla_t *card)
        }
 }
 
-static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev,
+static int setup_fr_header(struct sk_buff *skb, struct net_device* dev,
                           char op_mode)
 {
-       struct sk_buff *skb = *skb_orig;
        fr_channel_t *chan=dev->priv;
 
-       if (op_mode == WANPIPE){
-
+       if (op_mode == WANPIPE) {
                chan->fr_header[0]=Q922_UI;
                
                switch (htons(skb->protocol)){
-                       
                case ETH_P_IP:
                        chan->fr_header[1]=NLPID_IP;
                        break;
@@ -4894,16 +4889,14 @@ static int setup_fr_header(struct sk_buf
        }
 
        /* If we are in bridging mode, we must apply
-        * an Ethernet header */
-       if (op_mode == BRIDGE || op_mode == BRIDGE_NODE){
-
-
+        * an Ethernet header
+        */
+       if (op_mode == BRIDGE || op_mode == BRIDGE_NODE) {
                /* Encapsulate the packet as a bridged Ethernet frame. */
 #ifdef DEBUG
                printk(KERN_INFO "%s: encapsulating skb for frame relay\n", 
                        dev->name);
 #endif
-               
                chan->fr_header[0] = 0x03;
                chan->fr_header[1] = 0x00;
                chan->fr_header[2] = 0x80;
@@ -4916,7 +4909,6 @@ static int setup_fr_header(struct sk_buf
                /* Yuck. */
                skb->protocol = ETH_P_802_3;
                return 8;
-
        }
                
        return 0;
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -2903,19 +2903,18 @@ static struct net_device_stats *usbnet_g
  * completion callbacks.  2.5 should have fixed those bugs...
  */
 
-static void defer_bh (struct usbnet *dev, struct sk_buff *skb)
+static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct 
sk_buff_head *list)
 {
-       struct sk_buff_head     *list = skb->list;
        unsigned long           flags;
 
-       spin_lock_irqsave (&list->lock, flags);
-       __skb_unlink (skb, list);
-       spin_unlock (&list->lock);
-       spin_lock (&dev->done.lock);
-       __skb_queue_tail (&dev->done, skb);
+       spin_lock_irqsave(&list->lock, flags);
+       __skb_unlink(skb, list);
+       spin_unlock(&list->lock);
+       spin_lock(&dev->done.lock);
+       __skb_queue_tail(&dev->done, skb);
        if (dev->done.qlen == 1)
-               tasklet_schedule (&dev->bh);
-       spin_unlock_irqrestore (&dev->done.lock, flags);
+               tasklet_schedule(&dev->bh);
+       spin_unlock_irqrestore(&dev->done.lock, flags);
 }
 
 /* some work can't be done in tasklets, so we use keventd
@@ -3120,7 +3119,7 @@ block:
                break;
        }
 
-       defer_bh (dev, skb);
+       defer_bh(dev, skb, &dev->rxq);
 
        if (urb) {
                if (netif_running (dev->net)
@@ -3490,7 +3489,7 @@ static void tx_complete (struct urb *urb
 
        urb->dev = NULL;
        entry->state = tx_done;
-       defer_bh (dev, skb);
+       defer_bh(dev, skb, &dev->txq);
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -204,7 +204,6 @@ struct sk_buff {
        struct sk_buff          *next;
        struct sk_buff          *prev;
 
-       struct sk_buff_head     *list;
        struct sock             *sk;
        struct timeval          stamp;
        struct net_device       *dev;
@@ -597,7 +596,6 @@ static inline void __skb_queue_head(stru
 {
        struct sk_buff *prev, *next;
 
-       newsk->list = list;
        list->qlen++;
        prev = (struct sk_buff *)list;
        next = prev->next;
@@ -622,7 +620,6 @@ static inline void __skb_queue_tail(stru
 {
        struct sk_buff *prev, *next;
 
-       newsk->list = list;
        list->qlen++;
        next = (struct sk_buff *)list;
        prev = next->prev;
@@ -655,7 +652,6 @@ static inline struct sk_buff *__skb_dequ
                next->prev   = prev;
                prev->next   = next;
                result->next = result->prev = NULL;
-               result->list = NULL;
        }
        return result;
 }
@@ -664,7 +660,7 @@ static inline struct sk_buff *__skb_dequ
 /*
  *     Insert a packet on a list.
  */
-extern void        skb_insert(struct sk_buff *old, struct sk_buff *newsk);
+extern void        skb_insert(struct sk_buff *old, struct sk_buff *newsk, 
struct sk_buff_head *list);
 static inline void __skb_insert(struct sk_buff *newsk,
                                struct sk_buff *prev, struct sk_buff *next,
                                struct sk_buff_head *list)
@@ -672,24 +668,23 @@ static inline void __skb_insert(struct s
        newsk->next = next;
        newsk->prev = prev;
        next->prev  = prev->next = newsk;
-       newsk->list = list;
        list->qlen++;
 }
 
 /*
  *     Place a packet after a given packet in a list.
  */
-extern void       skb_append(struct sk_buff *old, struct sk_buff *newsk);
-static inline void __skb_append(struct sk_buff *old, struct sk_buff *newsk)
+extern void       skb_append(struct sk_buff *old, struct sk_buff *newsk, 
struct sk_buff_head *list);
+static inline void __skb_append(struct sk_buff *old, struct sk_buff *newsk, 
struct sk_buff_head *list)
 {
-       __skb_insert(newsk, old, old->next, old->list);
+       __skb_insert(newsk, old, old->next, list);
 }
 
 /*
  * remove sk_buff from list. _Must_ be called atomically, and with
  * the list known..
  */
-extern void       skb_unlink(struct sk_buff *skb);
+extern void       skb_unlink(struct sk_buff *skb, struct sk_buff_head *list);
 static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
 {
        struct sk_buff *next, *prev;
@@ -698,7 +693,6 @@ static inline void __skb_unlink(struct s
        next       = skb->next;
        prev       = skb->prev;
        skb->next  = skb->prev = NULL;
-       skb->list  = NULL;
        next->prev = prev;
        prev->next = next;
 }
diff --git a/net/atm/ipcommon.c b/net/atm/ipcommon.c
--- a/net/atm/ipcommon.c
+++ b/net/atm/ipcommon.c
@@ -34,7 +34,6 @@
 
 void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to)
 {
-       struct sk_buff *skb;
        unsigned long flags;
        struct sk_buff *skb_from = (struct sk_buff *) from;
        struct sk_buff *skb_to = (struct sk_buff *) to;
@@ -47,8 +46,6 @@ void skb_migrate(struct sk_buff_head *fr
        prev->next = skb_to;
        to->prev->next = from->next;
        to->prev = from->prev;
-       for (skb = from->next; skb != skb_to; skb = skb->next)
-               skb->list = to;
        to->qlen += from->qlen;
        spin_unlock(&to->lock);
        from->prev = skb_from;
diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
--- a/net/ax25/ax25_subr.c
+++ b/net/ax25/ax25_subr.c
@@ -76,7 +76,7 @@ void ax25_requeue_frames(ax25_cb *ax25)
                if (skb_prev == NULL)
                        skb_queue_head(&ax25->write_queue, skb);
                else
-                       skb_append(skb_prev, skb);
+                       skb_append(skb_prev, skb, &ax25->write_queue);
                skb_prev = skb;
        }
 }
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -281,8 +281,6 @@ void kfree_skbmem(struct sk_buff *skb)
 
 void __kfree_skb(struct sk_buff *skb)
 {
-       BUG_ON(skb->list != NULL);
-
        dst_release(skb->dst);
 #ifdef CONFIG_XFRM
        secpath_put(skb->sp);
@@ -333,7 +331,6 @@ struct sk_buff *skb_clone(struct sk_buff
 #define C(x) n->x = skb->x
 
        n->next = n->prev = NULL;
-       n->list = NULL;
        n->sk = NULL;
        C(stamp);
        C(dev);
@@ -403,7 +400,6 @@ static void copy_skb_header(struct sk_bu
         */
        unsigned long offset = new->data - old->data;
 
-       new->list       = NULL;
        new->sk         = NULL;
        new->dev        = old->dev;
        new->real_dev   = old->real_dev;
@@ -1342,50 +1338,43 @@ void skb_queue_tail(struct sk_buff_head 
        __skb_queue_tail(list, newsk);
        spin_unlock_irqrestore(&list->lock, flags);
 }
+
 /**
  *     skb_unlink      -       remove a buffer from a list
  *     @skb: buffer to remove
+ *     @list: list to use
  *
- *     Place a packet after a given packet in a list. The list locks are taken
- *     and this function is atomic with respect to other list locked calls
+ *     Remove a packet from a list. The list locks are taken and this
+ *     function is atomic with respect to other list locked calls
  *
- *     Works even without knowing the list it is sitting on, which can be
- *     handy at times. It also means that THE LIST MUST EXIST when you
- *     unlink. Thus a list must have its contents unlinked before it is
- *     destroyed.
+ *     You must know what list the SKB is on.
  */
-void skb_unlink(struct sk_buff *skb)
+void skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
 {
-       struct sk_buff_head *list = skb->list;
-
-       if (list) {
-               unsigned long flags;
+       unsigned long flags;
 
-               spin_lock_irqsave(&list->lock, flags);
-               if (skb->list == list)
-                       __skb_unlink(skb, skb->list);
-               spin_unlock_irqrestore(&list->lock, flags);
-       }
+       spin_lock_irqsave(&list->lock, flags);
+       __skb_unlink(skb, list);
+       spin_unlock_irqrestore(&list->lock, flags);
 }
 
-
 /**
  *     skb_append      -       append a buffer
  *     @old: buffer to insert after
  *     @newsk: buffer to insert
+ *     @list: list to use
  *
  *     Place a packet after a given packet in a list. The list locks are taken
  *     and this function is atomic with respect to other list locked calls.
  *     A buffer cannot be placed on two lists at the same time.
  */
-
-void skb_append(struct sk_buff *old, struct sk_buff *newsk)
+void skb_append(struct sk_buff *old, struct sk_buff *newsk, struct 
sk_buff_head *list)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&old->list->lock, flags);
-       __skb_append(old, newsk);
-       spin_unlock_irqrestore(&old->list->lock, flags);
+       spin_lock_irqsave(&list->lock, flags);
+       __skb_append(old, newsk, list);
+       spin_unlock_irqrestore(&list->lock, flags);
 }
 
 
@@ -1393,19 +1382,21 @@ void skb_append(struct sk_buff *old, str
  *     skb_insert      -       insert a buffer
  *     @old: buffer to insert before
  *     @newsk: buffer to insert
+ *     @list: list to use
+ *
+ *     Place a packet before a given packet in a list. The list locks are
+ *     taken and this function is atomic with respect to other list locked
+ *     calls.
  *
- *     Place a packet before a given packet in a list. The list locks are taken
- *     and this function is atomic with respect to other list locked calls
  *     A buffer cannot be placed on two lists at the same time.
  */
-
-void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
+void skb_insert(struct sk_buff *old, struct sk_buff *newsk, struct 
sk_buff_head *list)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&old->list->lock, flags);
-       __skb_insert(newsk, old->prev, old, old->list);
-       spin_unlock_irqrestore(&old->list->lock, flags);
+       spin_lock_irqsave(&list->lock, flags);
+       __skb_insert(newsk, old->prev, old, list);
+       spin_unlock_irqrestore(&list->lock, flags);
 }
 
 #if 0
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1763,7 +1763,7 @@ static int dn_recvmsg(struct kiocb *iocb
                nskb = skb->next;
 
                if (skb->len == 0) {
-                       skb_unlink(skb);
+                       skb_unlink(skb, queue);
                        kfree_skb(skb);
                        /* 
                         * N.B. Don't refer to skb or cb after this point
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -479,7 +479,7 @@ int dn_nsp_check_xmit_queue(struct sock 
                xmit_count = cb2->xmit_count;
                segnum = cb2->segnum;
                /* Remove and drop ack'ed packet */
-               skb_unlink(ack);
+               skb_unlink(ack, q);
                kfree_skb(ack);
                ack = NULL;
 
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -869,7 +869,7 @@ static void aun_tx_ack(unsigned long seq
 
 foundit:
        tx_result(skb->sk, eb->cookie, result);
-       skb_unlink(skb);
+       skb_unlink(skb, &aun_queue);
        spin_unlock_irqrestore(&aun_queue_lock, flags);
        kfree_skb(skb);
 }
@@ -947,7 +947,7 @@ static void ab_cleanup(unsigned long h)
                {
                        tx_result(skb->sk, eb->cookie, 
                                  ECTYPE_TRANSMIT_NOT_PRESENT);
-                       skb_unlink(skb);
+                       skb_unlink(skb, &aun_queue);
                        kfree_skb(skb);
                }
                skb = newskb;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -975,7 +975,7 @@ do_fault:
        if (!skb->len) {
                if (sk->sk_send_head == skb)
                        sk->sk_send_head = NULL;
-               __skb_unlink(skb, skb->list);
+               __skb_unlink(skb, &sk->sk_write_queue);
                sk_stream_free_skb(sk, skb);
        }
 
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2085,7 +2085,7 @@ static int tcp_clean_rtx_queue(struct so
                        seq_rtt = now - scb->when;
                tcp_dec_pcount_approx(&tp->fackets_out, skb);
                tcp_packets_out_dec(tp, skb);
-               __skb_unlink(skb, skb->list);
+               __skb_unlink(skb, &sk->sk_write_queue);
                sk_stream_free_skb(sk, skb);
        }
 
@@ -2853,7 +2853,7 @@ static void tcp_ofo_queue(struct sock *s
 
                if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
                        SOCK_DEBUG(sk, "ofo packet was already received \n");
-                       __skb_unlink(skb, skb->list);
+                       __skb_unlink(skb, &tp->out_of_order_queue);
                        __kfree_skb(skb);
                        continue;
                }
@@ -2861,7 +2861,7 @@ static void tcp_ofo_queue(struct sock *s
                           tp->rcv_nxt, TCP_SKB_CB(skb)->seq,
                           TCP_SKB_CB(skb)->end_seq);
 
-               __skb_unlink(skb, skb->list);
+               __skb_unlink(skb, &tp->out_of_order_queue);
                __skb_queue_tail(&sk->sk_receive_queue, skb);
                tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
                if(skb->h.th->fin)
@@ -3027,7 +3027,7 @@ drop:
                u32 end_seq = TCP_SKB_CB(skb)->end_seq;
 
                if (seq == TCP_SKB_CB(skb1)->end_seq) {
-                       __skb_append(skb1, skb);
+                       __skb_append(skb1, skb, &tp->out_of_order_queue);
 
                        if (!tp->rx_opt.num_sacks ||
                            tp->selective_acks[0].end_seq != seq)
@@ -3071,7 +3071,7 @@ drop:
                               tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, 
end_seq);
                               break;
                       }
-                      __skb_unlink(skb1, skb1->list);
+                      __skb_unlink(skb1, &tp->out_of_order_queue);
                       tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, 
TCP_SKB_CB(skb1)->end_seq);
                       __kfree_skb(skb1);
                }
@@ -3088,8 +3088,9 @@ add_sack:
  * simplifies code)
  */
 static void
-tcp_collapse(struct sock *sk, struct sk_buff *head,
-            struct sk_buff *tail, u32 start, u32 end)
+tcp_collapse(struct sock *sk, struct sk_buff_head *list,
+            struct sk_buff *head, struct sk_buff *tail,
+            u32 start, u32 end)
 {
        struct sk_buff *skb;
 
@@ -3099,7 +3100,7 @@ tcp_collapse(struct sock *sk, struct sk_
                /* No new bits? It is possible on ofo queue. */
                if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
                        struct sk_buff *next = skb->next;
-                       __skb_unlink(skb, skb->list);
+                       __skb_unlink(skb, list);
                        __kfree_skb(skb);
                        NET_INC_STATS_BH(LINUX_MIB_TCPRCVCOLLAPSED);
                        skb = next;
@@ -3145,7 +3146,7 @@ tcp_collapse(struct sock *sk, struct sk_
                nskb->mac.raw = nskb->head + (skb->mac.raw-skb->head);
                memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
                TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
-               __skb_insert(nskb, skb->prev, skb, skb->list);
+               __skb_insert(nskb, skb->prev, skb, list);
                sk_stream_set_owner_r(nskb, sk);
 
                /* Copy data, releasing collapsed skbs. */
@@ -3164,7 +3165,7 @@ tcp_collapse(struct sock *sk, struct sk_
                        }
                        if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
                                struct sk_buff *next = skb->next;
-                               __skb_unlink(skb, skb->list);
+                               __skb_unlink(skb, list);
                                __kfree_skb(skb);
                                NET_INC_STATS_BH(LINUX_MIB_TCPRCVCOLLAPSED);
                                skb = next;
@@ -3200,7 +3201,8 @@ static void tcp_collapse_ofo_queue(struc
                if (skb == (struct sk_buff *)&tp->out_of_order_queue ||
                    after(TCP_SKB_CB(skb)->seq, end) ||
                    before(TCP_SKB_CB(skb)->end_seq, start)) {
-                       tcp_collapse(sk, head, skb, start, end);
+                       tcp_collapse(sk, &tp->out_of_order_queue,
+                                    head, skb, start, end);
                        head = skb;
                        if (skb == (struct sk_buff *)&tp->out_of_order_queue)
                                break;
@@ -3237,7 +3239,8 @@ static int tcp_prune_queue(struct sock *
                tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
 
        tcp_collapse_ofo_queue(sk);
-       tcp_collapse(sk, sk->sk_receive_queue.next,
+       tcp_collapse(sk, &sk->sk_receive_queue,
+                    sk->sk_receive_queue.next,
                     (struct sk_buff*)&sk->sk_receive_queue,
                     tp->copied_seq, tp->rcv_nxt);
        sk_stream_mem_reclaim(sk);
@@ -3462,7 +3465,7 @@ static void tcp_check_urg(struct sock * 
                struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
                tp->copied_seq++;
                if (skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)) {
-                       __skb_unlink(skb, skb->list);
+                       __skb_unlink(skb, &sk->sk_receive_queue);
                        __kfree_skb(skb);
                }
        }
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -505,7 +505,7 @@ static int tcp_fragment(struct sock *sk,
 
        /* Link BUFF into the send queue. */
        skb_header_release(buff);
-       __skb_append(skb, buff);
+       __skb_append(skb, buff, &sk->sk_write_queue);
 
        return 0;
 }
@@ -893,7 +893,7 @@ static int tso_fragment(struct sock *sk,
 
        /* Link BUFF into the send queue. */
        skb_header_release(buff);
-       __skb_append(skb, buff);
+       __skb_append(skb, buff, &sk->sk_write_queue);
 
        return 0;
 }
@@ -1238,7 +1238,7 @@ static void tcp_retrans_try_collapse(str
                       tcp_skb_pcount(next_skb) != 1);
 
                /* Ok.  We will be able to collapse the packet. */
-               __skb_unlink(next_skb, next_skb->list);
+               __skb_unlink(next_skb, &sk->sk_write_queue);
 
                memcpy(skb_put(skb, next_skb_size), next_skb->data, 
next_skb_size);
 
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -988,9 +988,6 @@ void irlap_resend_rejected_frames(struct
                        IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
                        return;
                }
-               /* Unlink tx_skb from list */
-               tx_skb->next = tx_skb->prev = NULL;
-               tx_skb->list = NULL;
 
                /* Clear old Nr field + poll bit */
                tx_skb->data[1] &= 0x0f;
@@ -1063,9 +1060,6 @@ void irlap_resend_rejected_frame(struct 
                        IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
                        return;
                }
-               /* Unlink tx_skb from list */
-               tx_skb->next = tx_skb->prev = NULL;
-               tx_skb->list = NULL;
 
                /* Clear old Nr field + poll bit */
                tx_skb->data[1] &= 0x0f;
diff --git a/net/lapb/lapb_subr.c b/net/lapb/lapb_subr.c
--- a/net/lapb/lapb_subr.c
+++ b/net/lapb/lapb_subr.c
@@ -78,7 +78,7 @@ void lapb_requeue_frames(struct lapb_cb 
                if (!skb_prev)
                        skb_queue_head(&lapb->write_queue, skb);
                else
-                       skb_append(skb_prev, skb);
+                       skb_append(skb_prev, skb, &lapb->write_queue);
                skb_prev = skb;
        }
 }
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -714,7 +714,7 @@ static int llc_ui_recvmsg(struct kiocb *
        if (uaddr)
                memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
        msg->msg_namelen = sizeof(*uaddr);
-       if (!skb->list) {
+       if (!skb->next) {
 dgram_free:
                kfree_skb(skb);
        }
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -71,7 +71,11 @@ int llc_conn_state_process(struct sock *
 
        if (!ev->ind_prim && !ev->cfm_prim) {
                /* indicate or confirm not required */
-               if (!skb->list)
+               /* XXX this is not very pretty, perhaps we should store
+                * XXX indicate/confirm-needed state in the llc_conn_state_ev
+                * XXX control block of the SKB instead? -DaveM
+                */
+               if (!skb->next)
                        goto out_kfree_skb;
                goto out_skb_put;
        }
diff --git a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c
--- a/net/netrom/nr_subr.c
+++ b/net/netrom/nr_subr.c
@@ -77,7 +77,7 @@ void nr_requeue_frames(struct sock *sk)
                if (skb_prev == NULL)
                        skb_queue_head(&sk->sk_write_queue, skb);
                else
-                       skb_append(skb_prev, skb);
+                       skb_append(skb_prev, skb, &sk->sk_write_queue);
                skb_prev = skb;
        }
 }
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -74,7 +74,7 @@ void rose_requeue_frames(struct sock *sk
                if (skb_prev == NULL)
                        skb_queue_head(&sk->sk_write_queue, skb);
                else
-                       skb_append(skb_prev, skb);
+                       skb_append(skb_prev, skb, &sk->sk_write_queue);
                skb_prev = skb;
        }
 }
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4892,7 +4892,7 @@ static void sctp_sock_migrate(struct soc
        sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
                event = sctp_skb2event(skb);
                if (event->asoc == assoc) {
-                       __skb_unlink(skb, skb->list);
+                       __skb_unlink(skb, &oldsk->sk_receive_queue);
                        __skb_queue_tail(&newsk->sk_receive_queue, skb);
                }
        }
@@ -4921,7 +4921,7 @@ static void sctp_sock_migrate(struct soc
                sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
                        event = sctp_skb2event(skb);
                        if (event->asoc == assoc) {
-                               __skb_unlink(skb, skb->list);
+                               __skb_unlink(skb, &oldsp->pd_lobby);
                                __skb_queue_tail(queue, skb);
                        }
                }
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -50,9 +50,9 @@
 
 /* Forward declarations for internal helpers.  */
 static struct sctp_ulpevent * sctp_ulpq_reasm(struct sctp_ulpq *ulpq,
-                                               struct sctp_ulpevent *);
+                                             struct sctp_ulpevent *);
 static struct sctp_ulpevent * sctp_ulpq_order(struct sctp_ulpq *,
-                                               struct sctp_ulpevent *);
+                                             struct sctp_ulpevent *);
 
 /* 1st Level Abstractions */
 
@@ -125,7 +125,9 @@ int sctp_ulpq_tail_data(struct sctp_ulpq
                event = sctp_ulpq_order(ulpq, event);
        }
 
-       /* Send event to the ULP.  */
+       /* Send event to the ULP.  'event' is the sctp_ulpevent for
+        * very first SKB on the 'temp' list.
+        */
        if (event)
                sctp_ulpq_tail_event(ulpq, event);
 
@@ -158,14 +160,18 @@ static int sctp_ulpq_clear_pd(struct sct
        return sctp_clear_pd(ulpq->asoc->base.sk);
 }
 
-
-
+/* If the SKB of 'event' is on a list, it is the first such member
+ * of that list.
+ */
 int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
 {
        struct sock *sk = ulpq->asoc->base.sk;
-       struct sk_buff_head *queue;
+       struct sk_buff_head *queue, *skb_list;
+       struct sk_buff *skb = sctp_event2skb(event);
        int clear_pd = 0;
 
+       skb_list = (struct sk_buff_head *) skb->prev;
+
        /* If the socket is just going to throw this away, do not
         * even try to deliver it.
         */
@@ -197,10 +203,10 @@ int sctp_ulpq_tail_event(struct sctp_ulp
        /* If we are harvesting multiple skbs they will be
         * collected on a list.
         */
-       if (sctp_event2skb(event)->list)
-               sctp_skb_list_tail(sctp_event2skb(event)->list, queue);
+       if (skb_list)
+               sctp_skb_list_tail(skb_list, queue);
        else
-               __skb_queue_tail(queue, sctp_event2skb(event));
+               __skb_queue_tail(queue, skb);
 
        /* Did we just complete partial delivery and need to get
         * rolling again?  Move pending data to the receive
@@ -214,10 +220,11 @@ int sctp_ulpq_tail_event(struct sctp_ulp
        return 1;
 
 out_free:
-       if (sctp_event2skb(event)->list)
-               sctp_queue_purge_ulpevents(sctp_event2skb(event)->list);
+       if (skb_list)
+               sctp_queue_purge_ulpevents(skb_list);
        else
                sctp_ulpevent_free(event);
+
        return 0;
 }
 
@@ -269,7 +276,7 @@ static inline void sctp_ulpq_store_reasm
  * payload was fragmented on the way and ip had to reassemble them.
  * We add the rest of skb's to the first skb's fraglist.
  */
-static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff 
*f_frag, struct sk_buff *l_frag)
+static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head 
*queue, struct sk_buff *f_frag, struct sk_buff *l_frag)
 {
        struct sk_buff *pos;
        struct sctp_ulpevent *event;
@@ -294,7 +301,7 @@ static struct sctp_ulpevent *sctp_make_r
                skb_shinfo(f_frag)->frag_list = pos;
 
        /* Remove the first fragment from the reassembly queue.  */
-       __skb_unlink(f_frag, f_frag->list);
+       __skb_unlink(f_frag, queue);
        while (pos) {
 
                pnext = pos->next;
@@ -304,7 +311,7 @@ static struct sctp_ulpevent *sctp_make_r
                f_frag->data_len += pos->len;
 
                /* Remove the fragment from the reassembly queue.  */
-               __skb_unlink(pos, pos->list);
+               __skb_unlink(pos, queue);
        
                /* Break if we have reached the last fragment.  */
                if (pos == l_frag)
@@ -375,7 +382,7 @@ static inline struct sctp_ulpevent *sctp
 done:
        return retval;
 found:
-       retval = sctp_make_reassembled_event(first_frag, pos);
+       retval = sctp_make_reassembled_event(&ulpq->reasm, first_frag, pos);
        if (retval)
                retval->msg_flags |= MSG_EOR;
        goto done;
@@ -435,7 +442,7 @@ static inline struct sctp_ulpevent *sctp
         * further.
         */
 done:
-       retval = sctp_make_reassembled_event(first_frag, last_frag);
+       retval = sctp_make_reassembled_event(&ulpq->reasm, first_frag, 
last_frag);
        if (retval && is_last)
                retval->msg_flags |= MSG_EOR;
 
@@ -527,7 +534,7 @@ static inline struct sctp_ulpevent *sctp
         * further.
         */
 done:
-       retval = sctp_make_reassembled_event(first_frag, last_frag);
+       retval = sctp_make_reassembled_event(&ulpq->reasm, first_frag, 
last_frag);
        return retval;
 }
 
@@ -537,6 +544,7 @@ done:
 static inline void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
                                              struct sctp_ulpevent *event)
 {
+       struct sk_buff_head *event_list;
        struct sk_buff *pos, *tmp;
        struct sctp_ulpevent *cevent;
        struct sctp_stream *in;
@@ -547,6 +555,8 @@ static inline void sctp_ulpq_retrieve_or
        ssn = event->ssn;
        in  = &ulpq->asoc->ssnmap->in;
 
+       event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev;
+
        /* We are holding the chunks by stream, by SSN.  */
        sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
                cevent = (struct sctp_ulpevent *) pos->cb;
@@ -567,10 +577,10 @@ static inline void sctp_ulpq_retrieve_or
                /* Found it, so mark in the ssnmap. */
                sctp_ssn_next(in, sid);
 
-               __skb_unlink(pos, pos->list);
+               __skb_unlink(pos, &ulpq->lobby);
 
                /* Attach all gathered skbs to the event.  */
-               __skb_queue_tail(sctp_event2skb(event)->list, pos);
+               __skb_queue_tail(event_list, pos);
        }
 }
 
@@ -626,7 +636,7 @@ static inline void sctp_ulpq_store_order
 }
 
 static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
-                                               struct sctp_ulpevent *event)
+                                            struct sctp_ulpevent *event)
 {
        __u16 sid, ssn;
        struct sctp_stream *in;
@@ -667,7 +677,7 @@ static inline void sctp_ulpq_reap_ordere
 {
        struct sk_buff *pos, *tmp;
        struct sctp_ulpevent *cevent;
-       struct sctp_ulpevent *event = NULL;
+       struct sctp_ulpevent *event;
        struct sctp_stream *in;
        struct sk_buff_head temp;
        __u16 csid, cssn;
@@ -675,6 +685,8 @@ static inline void sctp_ulpq_reap_ordere
        in  = &ulpq->asoc->ssnmap->in;
 
        /* We are holding the chunks by stream, by SSN.  */
+       skb_queue_head_init(&temp);
+       event = NULL;
        sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
                cevent = (struct sctp_ulpevent *) pos->cb;
                csid = cevent->stream;
@@ -686,19 +698,20 @@ static inline void sctp_ulpq_reap_ordere
                /* Found it, so mark in the ssnmap. */         
                sctp_ssn_next(in, csid);
 
-               __skb_unlink(pos, pos->list);
+               __skb_unlink(pos, &ulpq->lobby);
                if (!event) {                                           
                        /* Create a temporary list to collect chunks on.  */
                        event = sctp_skb2event(pos);
-                       skb_queue_head_init(&temp);
                        __skb_queue_tail(&temp, sctp_event2skb(event));
                } else {
                        /* Attach all gathered skbs to the event.  */
-                       __skb_queue_tail(sctp_event2skb(event)->list, pos);
+                       __skb_queue_tail(&temp, pos);
                }
        }
 
-       /* Send event to the ULP.  */
+       /* Send event to the ULP.  'event' is the sctp_ulpevent for
+        * very first SKB on the 'temp' list.
+        */
        if (event)
                sctp_ulpq_tail_event(ulpq, event);
 }
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -286,16 +286,16 @@ void unix_gc(void)
                        skb = skb_peek(&s->sk_receive_queue);
                        while (skb &&
                               skb != (struct sk_buff *)&s->sk_receive_queue) {
-                               nextsk=skb->next;
+                               nextsk = skb->next;
                                /*
                                 *      Do we have file descriptors ?
                                 */
-                               if(UNIXCB(skb).fp)
-                               {
-                                       __skb_unlink(skb, skb->list);
-                                       __skb_queue_tail(&hitlist,skb);
+                               if (UNIXCB(skb).fp) {
+                                       __skb_unlink(skb,
+                                                    &s->sk_receive_queue);
+                                       __skb_queue_tail(&hitlist, skb);
                                }
-                               skb=nextsk;
+                               skb = nextsk;
                        }
                        spin_unlock(&s->sk_receive_queue.lock);
                }
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -80,7 +80,7 @@ void x25_requeue_frames(struct sock *sk)
                if (!skb_prev)
                        skb_queue_head(&sk->sk_write_queue, skb);
                else
-                       skb_append(skb_prev, skb);
+                       skb_append(skb_prev, skb, &sk->sk_write_queue);
                skb_prev = skb;
        }
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to