Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79fbe134 authored by Dongdong Deng's avatar Dongdong Deng Committed by David S. Miller
Browse files

drivers/net: using spin_lock_irqsave() in net_send_packet()



spin_unlock_irq() will enable interrupt in net_send_packet(),
this patch changes it to spin_lock_irqsave/spin_lock_irqrestore,
so that it doesn't enable interrupts when already disabled,
and netconsole would work properly over cs89x0/isa-skeleton.

Call trace:
netconsole write_msg()
{
 ...
 -> spin_lock_irqsave();
        -> netpoll_send_udp()
          -> netpoll_send_skb()
            -> net_send_packet()
              ->...

 -> spin_unlock_irqrestore();
 ...
}

Signed-off-by: default avatarDongdong Deng <dongdong.deng@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bc23283c
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -1524,6 +1524,7 @@ static void net_timeout(struct net_device *dev)
static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned long flags;

	if (net_debug > 3) {
		printk("%s: sent %d byte packet of type %x\n",
@@ -1535,7 +1536,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
                  ask the chip to start transmitting before the
                  whole packet has been completely uploaded. */

	spin_lock_irq(&lp->lock);
	spin_lock_irqsave(&lp->lock, flags);
	netif_stop_queue(dev);

	/* initiate a transmit sequence */
@@ -1549,13 +1550,13 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
		 * we're waiting for TxOk, so return 1 and requeue this packet.
		 */

		spin_unlock_irq(&lp->lock);
		spin_unlock_irqrestore(&lp->lock, flags);
		if (net_debug) printk("cs89x0: Tx buffer not free!\n");
		return NETDEV_TX_BUSY;
	}
	/* Write the contents of the packet */
	writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
	spin_unlock_irq(&lp->lock);
	spin_unlock_irqrestore(&lp->lock, flags);
	lp->stats.tx_bytes += skb->len;
	dev->trans_start = jiffies;
	dev_kfree_skb (skb);
+3 −2
Original line number Diff line number Diff line
@@ -430,7 +430,8 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
	 * hardware interrupt handler.  Queue flow control is
	 * thus managed under this lock as well.
	 */
	spin_lock_irq(&np->lock);
	unsigned long flags;
	spin_lock_irqsave(&np->lock, flags);

	add_to_tx_ring(np, skb, length);
	dev->trans_start = jiffies;
@@ -446,7 +447,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
	 * is when the transmit statistics are updated.
	 */

	spin_unlock_irq(&np->lock);
	spin_unlock_irqrestore(&np->lock, flags);
#else
	/* This is the case for older hardware which takes
	 * a single transmit buffer at a time, and it is