diff options
author | 2012-04-18 15:52:50 -0400 | |
---|---|---|
committer | 2012-04-18 15:52:50 -0400 | |
commit | 681e4a5e13c1c8315694eb4f44e0cdd84c9082d2 (patch) | |
tree | 699f14527c118859026e8ce0214e689d0b9c88cb /drivers/net/xen-netfront.c | |
parent | xen/p2m: m2p_find_override: use list_for_each_entry_safe (diff) | |
parent | Merge branch 'for-3.4/drivers' of git://git.kernel.dk/linux-block (diff) | |
download | linux-dev-681e4a5e13c1c8315694eb4f44e0cdd84c9082d2.tar.xz linux-dev-681e4a5e13c1c8315694eb4f44e0cdd84c9082d2.zip |
Merge commit 'c104f1fa1ecf4ee0fc06e31b1f77630b2551be81' into stable/for-linus-3.4
* commit 'c104f1fa1ecf4ee0fc06e31b1f77630b2551be81': (14566 commits)
cpufreq: OMAP: fix build errors: depends on ARCH_OMAP2PLUS
sparc64: Eliminate obsolete __handle_softirq() function
sparc64: Fix bootup crash on sun4v.
kconfig: delete last traces of __enabled_ from autoconf.h
Revert "kconfig: fix __enabled_ macros definition for invisible and un-selected symbols"
kconfig: fix IS_ENABLED to not require all options to be defined
irq_domain: fix type mismatch in debugfs output format
staging: android: fix mem leaks in __persistent_ram_init()
staging: vt6656: Don't leak memory in drivers/staging/vt6656/ioctl.c::private_ioctl()
staging: iio: hmc5843: Fix crash in probe function.
panic: fix stack dump print on direct call to panic()
drivers/rtc/rtc-pl031.c: enable clock on all ST variants
Revert "mm: vmscan: fix misused nr_reclaimed in shrink_mem_cgroup_zone()"
hugetlb: fix race condition in hugetlb_fault()
drivers/rtc/rtc-twl.c: use static register while reading time
drivers/rtc/rtc-s3c.c: add placeholder for driver private data
drivers/rtc/rtc-s3c.c: fix compilation error
MAINTAINERS: add PCDP console maintainer
memcg: do not open code accesses to res_counter members
drivers/rtc/rtc-efi.c: fix section mismatch warning
...
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r-- | drivers/net/xen-netfront.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index ccba19c72a36..0ebbb1906c30 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -69,7 +69,7 @@ struct netfront_cb { #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) -#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) +#define TX_MAX_TARGET min_t(int, NET_TX_RING_SIZE, 256) struct netfront_stats { u64 rx_packets; @@ -490,6 +490,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) int frags = skb_shinfo(skb)->nr_frags; unsigned int offset = offset_in_page(data); unsigned int len = skb_headlen(skb); + unsigned long flags; frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); if (unlikely(frags > MAX_SKB_FRAGS + 1)) { @@ -499,12 +500,12 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; } - spin_lock_irq(&np->tx_lock); + spin_lock_irqsave(&np->tx_lock, flags); if (unlikely(!netif_carrier_ok(dev) || (frags > 1 && !xennet_can_sg(dev)) || netif_needs_gso(skb, netif_skb_features(skb)))) { - spin_unlock_irq(&np->tx_lock); + spin_unlock_irqrestore(&np->tx_lock, flags); goto drop; } @@ -575,7 +576,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (!netfront_tx_slot_available(np)) netif_stop_queue(dev); - spin_unlock_irq(&np->tx_lock); + spin_unlock_irqrestore(&np->tx_lock, flags); return NETDEV_TX_OK; @@ -1229,6 +1230,33 @@ static int xennet_set_features(struct net_device *dev, return 0; } +static irqreturn_t xennet_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct netfront_info *np = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&np->tx_lock, flags); + + if (likely(netif_carrier_ok(dev))) { + xennet_tx_buf_gc(dev); + /* Under tx_lock: protects access to rx shared-ring indexes. */ + if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) + napi_schedule(&np->napi); + } + + spin_unlock_irqrestore(&np->tx_lock, flags); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void xennet_poll_controller(struct net_device *dev) +{ + xennet_interrupt(0, dev); +} +#endif + static const struct net_device_ops xennet_netdev_ops = { .ndo_open = xennet_open, .ndo_uninit = xennet_uninit, @@ -1240,6 +1268,9 @@ static const struct net_device_ops xennet_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_fix_features = xennet_fix_features, .ndo_set_features = xennet_set_features, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = xennet_poll_controller, +#endif }; static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev) @@ -1249,11 +1280,8 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev struct netfront_info *np; netdev = alloc_etherdev(sizeof(struct netfront_info)); - if (!netdev) { - printk(KERN_WARNING "%s> alloc_etherdev failed.\n", - __func__); + if (!netdev) return ERR_PTR(-ENOMEM); - } np = netdev_priv(netdev); np->xbdev = dev; @@ -1449,26 +1477,6 @@ static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]) return 0; } -static irqreturn_t xennet_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct netfront_info *np = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&np->tx_lock, flags); - - if (likely(netif_carrier_ok(dev))) { - xennet_tx_buf_gc(dev); - /* Under tx_lock: protects access to rx shared-ring indexes. */ - if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) - napi_schedule(&np->napi); - } - - spin_unlock_irqrestore(&np->tx_lock, flags); - - return IRQ_HANDLED; -} - static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) { struct xen_netif_tx_sring *txs; |