[S390]: Fix use of skb after netif_rx
authorJulia Lawall <julia@diku.dk>
Tue, 11 Dec 2007 01:17:37 +0000 (17:17 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Tue, 11 Dec 2007 10:45:29 +0000 (02:45 -0800)
Recently, Wang Chen submitted a patch
(d30f53aeb31d453a5230f526bea592af07944564) to move a call to netif_rx(skb)
after a subsequent reference to skb, because netif_rx may call kfree_skb on
its argument.  netif_rx_ni calls netif_rx, so the same problem occurs in
the files below.

I have left the updating of dev->last_rx after the calls to netif_rx_ni
because it seems time dependent, but moved the other field updates before.

This was found using the following semantic match.
(http://www.emn.fr/x-info/coccinelle/)

// <smpl>
@@
expression skb, e,e1;
@@

(
 netif_rx(skb);
|
 netif_rx_ni(skb);
)
  ... when != skb = e
(
  skb = e1
|
* skb
)
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/ctcmain.c
drivers/s390/net/netiucv.c

index 97adc701a819404da67bcbd6c55f973b868212ae..77a503139e327fe7d1597c8aec6bf43b0301b438 100644 (file)
@@ -478,14 +478,14 @@ ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                skb->dev = pskb->dev;
                skb->protocol = pskb->protocol;
                pskb->ip_summed = CHECKSUM_UNNECESSARY;
-               netif_rx_ni(skb);
                /**
-                * Successful rx; reset logflags
+                * reset logflags
                 */
                ch->logflags = 0;
-               dev->last_rx = jiffies;
                privptr->stats.rx_packets++;
                privptr->stats.rx_bytes += skb->len;
+               netif_rx_ni(skb);
+               dev->last_rx = jiffies;
                if (len > 0) {
                        skb_pull(pskb, header->length);
                        if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
index 4d18d6419ddc016fd08560bdef7f46af58335b5b..c7ea9381db9f63050b8589ee05faa466d295120e 100644 (file)
@@ -639,14 +639,14 @@ static void netiucv_unpack_skb(struct iucv_connection *conn,
                skb->dev = pskb->dev;
                skb->protocol = pskb->protocol;
                pskb->ip_summed = CHECKSUM_UNNECESSARY;
+               privptr->stats.rx_packets++;
+               privptr->stats.rx_bytes += skb->len;
                /*
                 * Since receiving is always initiated from a tasklet (in iucv.c),
                 * we must use netif_rx_ni() instead of netif_rx()
                 */
                netif_rx_ni(skb);
                dev->last_rx = jiffies;
-               privptr->stats.rx_packets++;
-               privptr->stats.rx_bytes += skb->len;
                skb_pull(pskb, header->next);
                skb_put(pskb, NETIUCV_HDRLEN);
        }