struct napi_struct napi;
- struct xen_netif_tx_front_ring tx;
- struct xen_netif_rx_front_ring rx;
-
- spinlock_t tx_lock;
- spinlock_t rx_lock;
-
unsigned int evtchn;
+ struct xenbus_device *xbdev;
- /* Receive-ring batched refills. */
-#define RX_MIN_TARGET 8
-#define RX_DFL_MIN_TARGET 64
-#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
- unsigned rx_min_target, rx_max_target, rx_target;
- struct sk_buff_head rx_batch;
-
- struct timer_list rx_refill_timer;
+ spinlock_t tx_lock;
+ struct xen_netif_tx_front_ring tx;
+ int tx_ring_ref;
/*
* {tx,rx}_skbs store outstanding skbuffs. Free tx_skb entries
*/
union skb_entry {
struct sk_buff *skb;
- unsigned link;
+ unsigned long link;
} tx_skbs[NET_TX_RING_SIZE];
grant_ref_t gref_tx_head;
grant_ref_t grant_tx_ref[NET_TX_RING_SIZE];
unsigned tx_skb_freelist;
+ spinlock_t rx_lock ____cacheline_aligned_in_smp;
+ struct xen_netif_rx_front_ring rx;
+ int rx_ring_ref;
+
+ /* Receive-ring batched refills. */
+#define RX_MIN_TARGET 8
+#define RX_DFL_MIN_TARGET 64
+#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
+ unsigned rx_min_target, rx_max_target, rx_target;
+ struct sk_buff_head rx_batch;
+
+ struct timer_list rx_refill_timer;
+
struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
grant_ref_t gref_rx_head;
grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
- struct xenbus_device *xbdev;
- int tx_ring_ref;
- int rx_ring_ref;
-
unsigned long rx_pfn_array[NET_RX_RING_SIZE];
struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
struct mmu_update rx_mmu[NET_RX_RING_SIZE];
struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
};
+static void skb_entry_set_link(union skb_entry *list, unsigned short id)
+{
+ list->link = id;
+}
+
+static int skb_entry_is_link(const union skb_entry *list)
+{
+ BUILD_BUG_ON(sizeof(list->skb) != sizeof(list->link));
+ return ((unsigned long)list->skb < PAGE_OFFSET);
+}
+
/*
* Access macros for acquiring freeing slots in tx_skbs[].
*/
static void add_id_to_freelist(unsigned *head, union skb_entry *list,
unsigned short id)
{
- list[id].link = *head;
+ skb_entry_set_link(&list[id], *head);
*head = id;
}
}
spin_unlock_bh(&np->rx_lock);
- xennet_maybe_wake_tx(dev);
+ netif_start_queue(dev);
return 0;
}
spin_lock(&np->rx_lock);
- if (unlikely(!netif_carrier_ok(dev))) {
- spin_unlock(&np->rx_lock);
- return 0;
- }
-
skb_queue_head_init(&rxq);
skb_queue_head_init(&errq);
skb_queue_head_init(&tmpq);
work_done++;
}
- while ((skb = __skb_dequeue(&errq)))
- kfree_skb(skb);
+ __skb_queue_purge(&errq);
work_done -= handle_incoming_queue(dev, &rxq);
for (i = 0; i < NET_TX_RING_SIZE; i++) {
/* Skip over entries which are actually freelist references */
- if ((unsigned long)np->tx_skbs[i].skb < PAGE_OFFSET)
+ if (skb_entry_is_link(&np->tx_skbs[i]))
continue;
skb = np->tx_skbs[i].skb;
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* Do all the remapping work and M2P updates. */
MULTI_mmu_update(mcl, np->rx_mmu, mmu - np->rx_mmu,
- 0, DOMID_SELF);
+ NULL, DOMID_SELF);
mcl++;
HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
}
}
- while ((skb = __skb_dequeue(&free_list)) != NULL)
- dev_kfree_skb(skb);
+ __skb_queue_purge(&free_list);
spin_unlock_bh(&np->rx_lock);
}
/* Initialise tx_skbs as a free chain containing every entry. */
np->tx_skb_freelist = 0;
for (i = 0; i < NET_TX_RING_SIZE; i++) {
- np->tx_skbs[i].link = i+1;
+ skb_entry_set_link(&np->tx_skbs[i], i+1);
np->grant_tx_ref[i] = GRANT_INVALID_REF;
}
goto fail;
}
- txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_KERNEL);
+ txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH);
if (!txs) {
err = -ENOMEM;
xenbus_dev_fatal(dev, err, "allocating tx ring page");
}
info->tx_ring_ref = err;
- rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_KERNEL);
+ rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH);
if (!rxs) {
err = -ENOMEM;
xenbus_dev_fatal(dev, err, "allocating rx ring page");
if (!feature_rx_copy) {
dev_info(&dev->dev,
- "backend does not support copying recieve path");
+ "backend does not support copying receive path\n");
return -ENODEV;
}
if (is_initial_xendomain())
return;
- return xenbus_unregister_driver(&netfront);
+ xenbus_unregister_driver(&netfront);
}
module_exit(netif_exit);
MODULE_DESCRIPTION("Xen virtual network device frontend");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("xen:vif");
+MODULE_ALIAS("xennet");