[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Clean up and re-indent netback driver.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 7fbaf67a0af5048f94640ea0e44b88408b21b791 # Parent 8bb3f2567b8c5c4b0d93dd1a8e2ee5ea0ea9f103 Clean up and re-indent netback driver. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 8bb3f2567b8c -r 7fbaf67a0af5 linux-2.6-xen-sparse/drivers/xen/netback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep 16 13:06:49 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep 16 13:27:01 2005 @@ -18,16 +18,10 @@ #include <asm-xen/xen-public/io/netif.h> #include <asm/io.h> #include <asm/pgalloc.h> - -#ifdef CONFIG_XEN_NETDEV_GRANT #include <asm-xen/xen-public/grant_table.h> #include <asm-xen/gnttab.h> #define GRANT_INVALID_REF (0xFFFF) - -#endif - - #if 0 #define ASSERT(_p) \ @@ -44,74 +38,73 @@ #define WPRINTK(fmt, args...) \ printk(KERN_WARNING "xen_net: " fmt, ##args) +typedef struct netif_st { + /* Unique identifier for this interface. */ + domid_t domid; + unsigned int handle; -typedef struct netif_st { - /* Unique identifier for this interface. */ - domid_t domid; - unsigned int handle; + u8 fe_dev_addr[6]; - u8 fe_dev_addr[6]; + /* Physical parameters of the comms window. */ + unsigned long tx_shmem_frame; +#ifdef CONFIG_XEN_NETDEV_GRANT + u16 tx_shmem_handle; + unsigned long tx_shmem_vaddr; + grant_ref_t tx_shmem_ref; +#endif + unsigned long rx_shmem_frame; +#ifdef CONFIG_XEN_NETDEV_GRANT + u16 rx_shmem_handle; + unsigned long rx_shmem_vaddr; + grant_ref_t rx_shmem_ref; +#endif + unsigned int evtchn; + unsigned int remote_evtchn; - /* Physical parameters of the comms window. */ - unsigned long tx_shmem_frame; + /* The shared rings and indexes. */ + netif_tx_interface_t *tx; + netif_rx_interface_t *rx; + + /* Private indexes into shared ring. */ + NETIF_RING_IDX rx_req_cons; + NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */ #ifdef CONFIG_XEN_NETDEV_GRANT - u16 tx_shmem_handle; - unsigned long tx_shmem_vaddr; - grant_ref_t tx_shmem_ref; + NETIF_RING_IDX rx_resp_prod_copy; #endif - unsigned long rx_shmem_frame; -#ifdef CONFIG_XEN_NETDEV_GRANT - u16 rx_shmem_handle; - unsigned long rx_shmem_vaddr; - grant_ref_t rx_shmem_ref; -#endif - unsigned int evtchn; - unsigned int remote_evtchn; + NETIF_RING_IDX tx_req_cons; + NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */ - /* The shared rings and indexes. */ - netif_tx_interface_t *tx; - netif_rx_interface_t *rx; + /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */ + unsigned long credit_bytes; + unsigned long credit_usec; + unsigned long remaining_credit; + struct timer_list credit_timeout; - /* Private indexes into shared ring. */ - NETIF_RING_IDX rx_req_cons; - NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */ -#ifdef CONFIG_XEN_NETDEV_GRANT - NETIF_RING_IDX rx_resp_prod_copy; /* private version of shared variable */ -#endif - NETIF_RING_IDX tx_req_cons; - NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */ + /* Miscellaneous private stuff. */ + enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; + int active; + struct list_head list; /* scheduling list */ + atomic_t refcnt; + struct net_device *dev; + struct net_device_stats stats; - /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */ - unsigned long credit_bytes; - unsigned long credit_usec; - unsigned long remaining_credit; - struct timer_list credit_timeout; - - /* Miscellaneous private stuff. */ - enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; - int active; - struct list_head list; /* scheduling list */ - atomic_t refcnt; - struct net_device *dev; - struct net_device_stats stats; - - struct work_struct free_work; + struct work_struct free_work; } netif_t; void netif_creditlimit(netif_t *netif); int netif_disconnect(netif_t *netif); netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]); -void free_netif_callback(netif_t *netif); +void free_netif(netif_t *netif); int netif_map(netif_t *netif, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int evtchn); #define netif_get(_b) (atomic_inc(&(_b)->refcnt)) -#define netif_put(_b) \ - do { \ - if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - free_netif_callback(_b); \ - } while (0) +#define netif_put(_b) \ + do { \ + if ( atomic_dec_and_test(&(_b)->refcnt) ) \ + free_netif(_b); \ + } while (0) void netif_xenbus_init(void); @@ -123,3 +116,13 @@ irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs); #endif /* __NETIF__BACKEND__COMMON_H__ */ + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -r 8bb3f2567b8c -r 7fbaf67a0af5 linux-2.6-xen-sparse/drivers/xen/netback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Fri Sep 16 13:06:49 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Fri Sep 16 13:27:01 2005 @@ -11,104 +11,105 @@ static void __netif_up(netif_t *netif) { - struct net_device *dev = netif->dev; - spin_lock_bh(&dev->xmit_lock); - netif->active = 1; - spin_unlock_bh(&dev->xmit_lock); - (void)bind_evtchn_to_irqhandler( - netif->evtchn, netif_be_int, 0, dev->name, netif); - netif_schedule_work(netif); + struct net_device *dev = netif->dev; + spin_lock_bh(&dev->xmit_lock); + netif->active = 1; + spin_unlock_bh(&dev->xmit_lock); + (void)bind_evtchn_to_irqhandler( + netif->evtchn, netif_be_int, 0, dev->name, netif); + netif_schedule_work(netif); } static void __netif_down(netif_t *netif) { - struct net_device *dev = netif->dev; - spin_lock_bh(&dev->xmit_lock); - netif->active = 0; - spin_unlock_bh(&dev->xmit_lock); - unbind_evtchn_from_irqhandler(netif->evtchn, netif); - netif_deschedule_work(netif); + struct net_device *dev = netif->dev; + spin_lock_bh(&dev->xmit_lock); + netif->active = 0; + spin_unlock_bh(&dev->xmit_lock); + unbind_evtchn_from_irqhandler(netif->evtchn, netif); + netif_deschedule_work(netif); } static int net_open(struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - if (netif->status == CONNECTED) - __netif_up(netif); - netif_start_queue(dev); - return 0; + netif_t *netif = netdev_priv(dev); + if (netif->status == CONNECTED) + __netif_up(netif); + netif_start_queue(dev); + return 0; } static int net_close(struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - netif_stop_queue(dev); - if (netif->status == CONNECTED) - __netif_down(netif); - return 0; + netif_t *netif = netdev_priv(dev); + netif_stop_queue(dev); + if (netif->status == CONNECTED) + __netif_down(netif); + return 0; } netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]) { - int err = 0, i; - struct net_device *dev; - netif_t *netif; - char name[IFNAMSIZ] = {}; - - snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); - dev = alloc_netdev(sizeof(netif_t), name, ether_setup); - if (dev == NULL) { - DPRINTK("Could not create netif: out of memory\n"); - return NULL; - } - - netif = netdev_priv(dev); - memset(netif, 0, sizeof(*netif)); - netif->domid = domid; - netif->handle = handle; - netif->status = DISCONNECTED; - atomic_set(&netif->refcnt, 0); - netif->dev = dev; - - netif->credit_bytes = netif->remaining_credit = ~0UL; - netif->credit_usec = 0UL; - init_timer(&netif->credit_timeout); - - dev->hard_start_xmit = netif_be_start_xmit; - dev->get_stats = netif_be_get_stats; - dev->open = net_open; - dev->stop = net_close; - dev->features = NETIF_F_NO_CSUM; - - /* Disable queuing. */ - dev->tx_queue_len = 0; - - for (i = 0; i < ETH_ALEN; i++) - if (be_mac[i] != 0) - break; - if (i == ETH_ALEN) { - /* - * Initialise a dummy MAC address. We choose the numerically largest - * non-broadcast address to prevent the address getting stolen by an - * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF) - */ - memset(dev->dev_addr, 0xFF, ETH_ALEN); - dev->dev_addr[0] &= ~0x01; - } else - memcpy(dev->dev_addr, be_mac, ETH_ALEN); - - rtnl_lock(); - err = register_netdevice(dev); - rtnl_unlock(); - if (err) { - DPRINTK("Could not register new net device %s: err=%d\n", - dev->name, err); - free_netdev(dev); - return NULL; - } - - DPRINTK("Successfully created netif\n"); - return netif; + int err = 0, i; + struct net_device *dev; + netif_t *netif; + char name[IFNAMSIZ] = {}; + + snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); + dev = alloc_netdev(sizeof(netif_t), name, ether_setup); + if (dev == NULL) { + DPRINTK("Could not create netif: out of memory\n"); + return NULL; + } + + netif = netdev_priv(dev); + memset(netif, 0, sizeof(*netif)); + netif->domid = domid; + netif->handle = handle; + netif->status = DISCONNECTED; + atomic_set(&netif->refcnt, 0); + netif->dev = dev; + + netif->credit_bytes = netif->remaining_credit = ~0UL; + netif->credit_usec = 0UL; + init_timer(&netif->credit_timeout); + + dev->hard_start_xmit = netif_be_start_xmit; + dev->get_stats = netif_be_get_stats; + dev->open = net_open; + dev->stop = net_close; + dev->features = NETIF_F_NO_CSUM; + + /* Disable queuing. */ + dev->tx_queue_len = 0; + + for (i = 0; i < ETH_ALEN; i++) + if (be_mac[i] != 0) + break; + if (i == ETH_ALEN) { + /* + * Initialise a dummy MAC address. We choose the numerically + * largest non-broadcast address to prevent the address getting + * stolen by an Ethernet bridge for STP purposes. + * (FE:FF:FF:FF:FF:FF) + */ + memset(dev->dev_addr, 0xFF, ETH_ALEN); + dev->dev_addr[0] &= ~0x01; + } else + memcpy(dev->dev_addr, be_mac, ETH_ALEN); + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + DPRINTK("Could not register new net device %s: err=%d\n", + dev->name, err); + free_netdev(dev); + return NULL; + } + + DPRINTK("Successfully created netif\n"); + return netif; } static int map_frontend_pages(netif_t *netif, unsigned long localaddr, @@ -116,191 +117,204 @@ unsigned long rx_ring_ref) { #ifdef CONFIG_XEN_NETDEV_GRANT - struct gnttab_map_grant_ref op; - - /* Map: Use the Grant table reference */ - op.host_addr = localaddr; - op.flags = GNTMAP_host_map; - op.ref = tx_ring_ref; - op.dom = netif->domid; + struct gnttab_map_grant_ref op; + + /* Map: Use the Grant table reference */ + op.host_addr = localaddr; + op.flags = GNTMAP_host_map; + op.ref = tx_ring_ref; + op.dom = netif->domid; - BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); - if (op.handle < 0) { - DPRINTK(" Grant table operation failure mapping tx_ring_ref!\n"); - return op.handle; - } - - netif->tx_shmem_ref = tx_ring_ref; - netif->tx_shmem_handle = op.handle; - netif->tx_shmem_vaddr = localaddr; - - /* Map: Use the Grant table reference */ - op.host_addr = localaddr + PAGE_SIZE; - op.flags = GNTMAP_host_map; - op.ref = rx_ring_ref; - op.dom = netif->domid; - - BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); - if (op.handle < 0) { - DPRINTK(" Grant table operation failure mapping rx_ring_ref!\n"); - return op.handle; - } - - netif->rx_shmem_ref = rx_ring_ref; - netif->rx_shmem_handle = op.handle; - netif->rx_shmem_vaddr = localaddr + PAGE_SIZE; + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); + if (op.handle < 0) { + DPRINTK(" Gnttab failure mapping tx_ring_ref!\n"); + return op.handle; + } + + netif->tx_shmem_ref = tx_ring_ref; + netif->tx_shmem_handle = op.handle; + netif->tx_shmem_vaddr = localaddr; + + /* Map: Use the Grant table reference */ + op.host_addr = localaddr + PAGE_SIZE; + op.flags = GNTMAP_host_map; + op.ref = rx_ring_ref; + op.dom = netif->domid; + + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); + if (op.handle < 0) { + DPRINTK(" Gnttab failure mapping rx_ring_ref!\n"); + return op.handle; + } + + netif->rx_shmem_ref = rx_ring_ref; + netif->rx_shmem_handle = op.handle; + netif->rx_shmem_vaddr = localaddr + PAGE_SIZE; #else - pgprot_t prot = __pgprot(_KERNPG_TABLE); - int err; - - err = direct_remap_pfn_range(&init_mm, localaddr, - tx_ring_ref, PAGE_SIZE, - prot, netif->domid); + pgprot_t prot = __pgprot(_KERNPG_TABLE); + int err; + + err = direct_remap_pfn_range( + &init_mm, localaddr, + tx_ring_ref, PAGE_SIZE, + prot, netif->domid); - err |= direct_remap_pfn_range(&init_mm, localaddr + PAGE_SIZE, - rx_ring_ref, PAGE_SIZE, - prot, netif->domid); - - if (err) - return err; + err |= direct_remap_pfn_range( + &init_mm, localaddr + PAGE_SIZE, + rx_ring_ref, PAGE_SIZE, + prot, netif->domid); + + if (err) + return err; #endif - return 0; + return 0; } static void unmap_frontend_pages(netif_t *netif) { #ifdef CONFIG_XEN_NETDEV_GRANT - struct gnttab_unmap_grant_ref op; - - op.host_addr = netif->tx_shmem_vaddr; - op.handle = netif->tx_shmem_handle; - op.dev_bus_addr = 0; - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); - - op.host_addr = netif->rx_shmem_vaddr; - op.handle = netif->rx_shmem_handle; - op.dev_bus_addr = 0; - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + struct gnttab_unmap_grant_ref op; + + op.host_addr = netif->tx_shmem_vaddr; + op.handle = netif->tx_shmem_handle; + op.dev_bus_addr = 0; + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + + op.host_addr = netif->rx_shmem_vaddr; + op.handle = netif->rx_shmem_handle; + op.dev_bus_addr = 0; + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); #endif - return; + return; } int netif_map(netif_t *netif, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int evtchn) { - struct vm_struct *vma; - evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain }; - int err; - - vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP); - if (vma == NULL) - return -ENOMEM; - - err = map_frontend_pages(netif, (unsigned long)vma->addr, tx_ring_ref, - rx_ring_ref); - if (err) { - vfree(vma->addr); - return err; - } - - op.u.bind_interdomain.dom1 = DOMID_SELF; - op.u.bind_interdomain.dom2 = netif->domid; - op.u.bind_interdomain.port1 = 0; - op.u.bind_interdomain.port2 = evtchn; - err = HYPERVISOR_event_channel_op(&op); - if (err) { - unmap_frontend_pages(netif); - vfree(vma->addr); - return err; - } - - netif->evtchn = op.u.bind_interdomain.port1; - netif->remote_evtchn = evtchn; - - netif->tx = (netif_tx_interface_t *)vma->addr; - netif->rx = (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); - netif->tx->resp_prod = netif->rx->resp_prod = 0; - netif_get(netif); - wmb(); /* Other CPUs see new state before interface is started. */ - - rtnl_lock(); - netif->status = CONNECTED; - wmb(); - if (netif_running(netif->dev)) - __netif_up(netif); - rtnl_unlock(); - - return 0; -} - -static void free_netif(void *arg) -{ - evtchn_op_t op = { .cmd = EVTCHNOP_close }; - netif_t *netif = (netif_t *)arg; - - /* - * These can't be done in netif_disconnect() because at that point there - * may be outstanding requests in the network stack whose asynchronous - * responses must still be notified to the remote driver. - */ - - op.u.close.port = netif->evtchn; - op.u.close.dom = DOMID_SELF; - HYPERVISOR_event_channel_op(&op); - op.u.close.port = netif->remote_evtchn; - op.u.close.dom = netif->domid; - HYPERVISOR_event_channel_op(&op); - - unregister_netdev(netif->dev); - - if (netif->tx) { - unmap_frontend_pages(netif); - vfree(netif->tx); /* Frees netif->rx as well. */ - } - - free_netdev(netif->dev); -} - -void free_netif_callback(netif_t *netif) -{ - INIT_WORK(&netif->free_work, free_netif, (void *)netif); - schedule_work(&netif->free_work); + struct vm_struct *vma; + evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain }; + int err; + + vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP); + if (vma == NULL) + return -ENOMEM; + + err = map_frontend_pages( + netif, (unsigned long)vma->addr, tx_ring_ref, rx_ring_ref); + if (err) { + vfree(vma->addr); + return err; + } + + op.u.bind_interdomain.dom1 = DOMID_SELF; + op.u.bind_interdomain.dom2 = netif->domid; + op.u.bind_interdomain.port1 = 0; + op.u.bind_interdomain.port2 = evtchn; + err = HYPERVISOR_event_channel_op(&op); + if (err) { + unmap_frontend_pages(netif); + vfree(vma->addr); + return err; + } + + netif->evtchn = op.u.bind_interdomain.port1; + netif->remote_evtchn = evtchn; + + netif->tx = (netif_tx_interface_t *)vma->addr; + netif->rx = (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); + netif->tx->resp_prod = netif->rx->resp_prod = 0; + netif_get(netif); + wmb(); /* Other CPUs see new state before interface is started. */ + + rtnl_lock(); + netif->status = CONNECTED; + wmb(); + if (netif_running(netif->dev)) + __netif_up(netif); + rtnl_unlock(); + + return 0; +} + +static void free_netif_callback(void *arg) +{ + evtchn_op_t op = { .cmd = EVTCHNOP_close }; + netif_t *netif = (netif_t *)arg; + + /* + * These can't be done in netif_disconnect() because at that point + * there may be outstanding requests in the network stack whose + * asynchronous responses must still be notified to the remote driver. + */ + + op.u.close.port = netif->evtchn; + op.u.close.dom = DOMID_SELF; + HYPERVISOR_event_channel_op(&op); + op.u.close.port = netif->remote_evtchn; + op.u.close.dom = netif->domid; + HYPERVISOR_event_channel_op(&op); + + unregister_netdev(netif->dev); + + if (netif->tx) { + unmap_frontend_pages(netif); + vfree(netif->tx); /* Frees netif->rx as well. */ + } + + free_netdev(netif->dev); +} + +void free_netif(netif_t *netif) +{ + INIT_WORK(&netif->free_work, free_netif_callback, (void *)netif); + schedule_work(&netif->free_work); } void netif_creditlimit(netif_t *netif) { #if 0 - /* Set the credit limit (reset remaining credit to new limit). */ - netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes; - netif->credit_usec = creditlimit->period_usec; - - if (netif->status == CONNECTED) { - /* - * Schedule work so that any packets waiting under previous credit - * limit are dealt with (acts like a replenishment point). - */ - netif->credit_timeout.expires = jiffies; - netif_schedule_work(netif); - } + /* Set the credit limit (reset remaining credit to new limit). */ + netif->credit_bytes = creditlimit->credit_bytes; + netif->remaining_credit = creditlimit->credit_bytes; + netif->credit_usec = creditlimit->period_usec; + + if (netif->status == CONNECTED) { + /* + * Schedule work so that any packets waiting under previous + * credit limit are dealt with (acts as a replenishment point). + */ + netif->credit_timeout.expires = jiffies; + netif_schedule_work(netif); + } #endif } int netif_disconnect(netif_t *netif) { - if (netif->status == CONNECTED) { - rtnl_lock(); - netif->status = DISCONNECTING; - wmb(); - if (netif_running(netif->dev)) - __netif_down(netif); - rtnl_unlock(); - netif_put(netif); - return 0; /* Caller should not send response message. */ - } - - return 1; -} + if (netif->status == CONNECTED) { + rtnl_lock(); + netif->status = DISCONNECTING; + wmb(); + if (netif_running(netif->dev)) + __netif_down(netif); + rtnl_unlock(); + netif_put(netif); + return 0; /* Caller should not send response message. */ + } + + return 1; +} + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -r 8bb3f2567b8c -r 7fbaf67a0af5 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Sep 16 13:06:49 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Sep 16 13:27:01 2005 @@ -57,8 +57,8 @@ #define PKT_PROT_LEN 64 static struct { - netif_tx_request_t req; - netif_t *netif; + netif_tx_request_t req; + netif_t *netif; } pending_tx_info[MAX_PENDING_REQS]; static u16 pending_ring[MAX_PENDING_REQS]; typedef unsigned int PEND_RING_IDX; @@ -91,49 +91,49 @@ static unsigned long alloc_mfn(void) { - unsigned long mfn = 0, flags; - struct xen_memory_reservation reservation = { - .extent_start = mfn_list, - .nr_extents = MAX_MFN_ALLOC, - .extent_order = 0, - .domid = DOMID_SELF - }; - spin_lock_irqsave(&mfn_lock, flags); - if ( unlikely(alloc_index == 0) ) - alloc_index = HYPERVISOR_memory_op( - XENMEM_increase_reservation, &reservation); - if ( alloc_index != 0 ) - mfn = mfn_list[--alloc_index]; - spin_unlock_irqrestore(&mfn_lock, flags); - return mfn; + unsigned long mfn = 0, flags; + struct xen_memory_reservation reservation = { + .extent_start = mfn_list, + .nr_extents = MAX_MFN_ALLOC, + .extent_order = 0, + .domid = DOMID_SELF + }; + spin_lock_irqsave(&mfn_lock, flags); + if ( unlikely(alloc_index == 0) ) + alloc_index = HYPERVISOR_memory_op( + XENMEM_increase_reservation, &reservation); + if ( alloc_index != 0 ) + mfn = mfn_list[--alloc_index]; + spin_unlock_irqrestore(&mfn_lock, flags); + return mfn; } #ifndef CONFIG_XEN_NETDEV_GRANT static void free_mfn(unsigned long mfn) { - unsigned long flags; - struct xen_memory_reservation reservation = { - .extent_start = &mfn, - .nr_extents = 1, - .extent_order = 0, - .domid = DOMID_SELF - }; - spin_lock_irqsave(&mfn_lock, flags); - if ( alloc_index != MAX_MFN_ALLOC ) - mfn_list[alloc_index++] = mfn; - else if ( HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation) - != 1 ) - BUG(); - spin_unlock_irqrestore(&mfn_lock, flags); + unsigned long flags; + struct xen_memory_reservation reservation = { + .extent_start = &mfn, + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; + spin_lock_irqsave(&mfn_lock, flags); + if ( alloc_index != MAX_MFN_ALLOC ) + mfn_list[alloc_index++] = mfn; + else + BUG_ON(HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation) != 1); + spin_unlock_irqrestore(&mfn_lock, flags); } #endif static inline void maybe_schedule_tx_action(void) { - smp_mb(); - if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && - !list_empty(&net_schedule_list) ) - tasklet_schedule(&net_tx_tasklet); + smp_mb(); + if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && + !list_empty(&net_schedule_list)) + tasklet_schedule(&net_tx_tasklet); } /* @@ -142,77 +142,77 @@ */ static inline int is_xen_skb(struct sk_buff *skb) { - extern kmem_cache_t *skbuff_cachep; - kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next; - return (cp == skbuff_cachep); + extern kmem_cache_t *skbuff_cachep; + kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next; + return (cp == skbuff_cachep); } int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - - ASSERT(skb->dev == dev); - - /* Drop the packet if the target domain has no receive buffers. */ - if ( !netif->active || - (netif->rx_req_cons == netif->rx->req_prod) || - ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) ) - goto drop; - - /* - * We do not copy the packet unless: - * 1. The data is shared; or - * 2. The data is not allocated from our special cache. - * NB. We also couldn't cope with fragmented packets, but we won't get - * any because we not advertise the NETIF_F_SG feature. - */ - if ( skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb) ) - { - int hlen = skb->data - skb->head; - struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); - if ( unlikely(nskb == NULL) ) - goto drop; - skb_reserve(nskb, hlen); - __skb_put(nskb, skb->len); - if (skb_copy_bits(skb, -hlen, nskb->data - hlen, skb->len + hlen)) - BUG(); - nskb->dev = skb->dev; - nskb->proto_csum_valid = skb->proto_csum_valid; - dev_kfree_skb(skb); - skb = nskb; - } + netif_t *netif = netdev_priv(dev); + + ASSERT(skb->dev == dev); + + /* Drop the packet if the target domain has no receive buffers. */ + if (!netif->active || + (netif->rx_req_cons == netif->rx->req_prod) || + ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE)) + goto drop; + + /* + * We do not copy the packet unless: + * 1. The data is shared; or + * 2. The data is not allocated from our special cache. + * NB. We also couldn't cope with fragmented packets, but we won't get + * any because we not advertise the NETIF_F_SG feature. + */ + if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) { + int hlen = skb->data - skb->head; + struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); + if ( unlikely(nskb == NULL) ) + goto drop; + skb_reserve(nskb, hlen); + __skb_put(nskb, skb->len); + BUG_ON(skb_copy_bits(skb, -hlen, nskb->data - hlen, + skb->len + hlen)); + nskb->dev = skb->dev; + nskb->proto_csum_valid = skb->proto_csum_valid; + dev_kfree_skb(skb); + skb = nskb; + } #ifdef CONFIG_XEN_NETDEV_GRANT #ifdef DEBUG_GRANT - printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d id=%04x gr=%04x\n", - netif->rx->req_prod, - netif->rx_req_cons, - netif->rx->ring[ - MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.id, - netif->rx->ring[ - MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.gref); -#endif -#endif - netif->rx_req_cons++; - netif_get(netif); - - skb_queue_tail(&rx_queue, skb); - tasklet_schedule(&net_rx_tasklet); - - return 0; + printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d " + "id=%04x gr=%04x\n", + netif->rx->req_prod, + netif->rx_req_cons, + netif->rx->ring[ + MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.id, + netif->rx->ring[ + MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.gref); +#endif +#endif + netif->rx_req_cons++; + netif_get(netif); + + skb_queue_tail(&rx_queue, skb); + tasklet_schedule(&net_rx_tasklet); + + return 0; drop: - netif->stats.tx_dropped++; - dev_kfree_skb(skb); - return 0; + netif->stats.tx_dropped++; + dev_kfree_skb(skb); + return 0; } #if 0 static void xen_network_done_notify(void) { - static struct net_device *eth0_dev = NULL; - if ( unlikely(eth0_dev == NULL) ) - eth0_dev = __dev_get_by_name("eth0"); - netif_rx_schedule(eth0_dev); + static struct net_device *eth0_dev = NULL; + if (unlikely(eth0_dev == NULL)) + eth0_dev = __dev_get_by_name("eth0"); + netif_rx_schedule(eth0_dev); } /* * Add following to poll() function in NAPI driver (Tigon3 is example): @@ -221,658 +221,654 @@ */ int xen_network_done(void) { - return skb_queue_empty(&rx_queue); + return skb_queue_empty(&rx_queue); } #endif static void net_rx_action(unsigned long unused) { - netif_t *netif = NULL; - s8 status; - u16 size, id, evtchn; - multicall_entry_t *mcl; - mmu_update_t *mmu; -#ifdef CONFIG_XEN_NETDEV_GRANT - gnttab_transfer_t *gop; -#else - struct mmuext_op *mmuext; -#endif - unsigned long vdata, old_mfn, new_mfn; - struct sk_buff_head rxq; - struct sk_buff *skb; - u16 notify_list[NETIF_RX_RING_SIZE]; - int notify_nr = 0; - - skb_queue_head_init(&rxq); - - mcl = rx_mcl; - mmu = rx_mmu; -#ifdef CONFIG_XEN_NETDEV_GRANT - gop = grant_rx_op; -#else - mmuext = rx_mmuext; -#endif - - while ( (skb = skb_dequeue(&rx_queue)) != NULL ) - { - netif = netdev_priv(skb->dev); - vdata = (unsigned long)skb->data; - old_mfn = virt_to_mfn(vdata); - - /* Memory squeeze? Back off for an arbitrary while. */ - if ( (new_mfn = alloc_mfn()) == 0 ) - { - if ( net_ratelimit() ) - WPRINTK("Memory squeeze in netback driver.\n"); - mod_timer(&net_timer, jiffies + HZ); - skb_queue_head(&rx_queue, skb); - break; - } - /* - * Set the new P2M table entry before reassigning the old data page. - * Heed the comment in pgtable-2level.h:pte_page(). :-) - */ - phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn; - - MULTI_update_va_mapping(mcl, vdata, - pfn_pte_ma(new_mfn, PAGE_KERNEL), 0); - mcl++; - -#ifdef CONFIG_XEN_NETDEV_GRANT - gop->mfn = old_mfn; - gop->domid = netif->domid; - gop->ref = netif->rx->ring[ - MASK_NETIF_RX_IDX(netif->rx_resp_prod_copy)].req.gref; - netif->rx_resp_prod_copy++; - gop++; -#else - mcl->op = __HYPERVISOR_mmuext_op; - mcl->args[0] = (unsigned long)mmuext; - mcl->args[1] = 1; - mcl->args[2] = 0; - mcl->args[3] = netif->domid; - mcl++; - - mmuext->cmd = MMUEXT_REASSIGN_PAGE; - mmuext->arg1.mfn = old_mfn; - mmuext++; -#endif - mmu->ptr = ((unsigned long long)new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; - mmu->val = __pa(vdata) >> PAGE_SHIFT; - mmu++; - - __skb_queue_tail(&rxq, skb); + netif_t *netif = NULL; + s8 status; + u16 size, id, evtchn; + multicall_entry_t *mcl; + mmu_update_t *mmu; +#ifdef CONFIG_XEN_NETDEV_GRANT + gnttab_transfer_t *gop; +#else + struct mmuext_op *mmuext; +#endif + unsigned long vdata, old_mfn, new_mfn; + struct sk_buff_head rxq; + struct sk_buff *skb; + u16 notify_list[NETIF_RX_RING_SIZE]; + int notify_nr = 0; + + skb_queue_head_init(&rxq); + + mcl = rx_mcl; + mmu = rx_mmu; +#ifdef CONFIG_XEN_NETDEV_GRANT + gop = grant_rx_op; +#else + mmuext = rx_mmuext; +#endif + + while ((skb = skb_dequeue(&rx_queue)) != NULL) { + netif = netdev_priv(skb->dev); + vdata = (unsigned long)skb->data; + old_mfn = virt_to_mfn(vdata); + + /* Memory squeeze? Back off for an arbitrary while. */ + if ((new_mfn = alloc_mfn()) == 0) { + if ( net_ratelimit() ) + WPRINTK("Memory squeeze in netback driver.\n"); + mod_timer(&net_timer, jiffies + HZ); + skb_queue_head(&rx_queue, skb); + break; + } + /* + * Set the new P2M table entry before reassigning the old data + * page. Heed the comment in pgtable-2level.h:pte_page(). :-) + */ + phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = + new_mfn; + + MULTI_update_va_mapping(mcl, vdata, + pfn_pte_ma(new_mfn, PAGE_KERNEL), 0); + mcl++; + +#ifdef CONFIG_XEN_NETDEV_GRANT + gop->mfn = old_mfn; + gop->domid = netif->domid; + gop->ref = netif->rx->ring[ + MASK_NETIF_RX_IDX(netif->rx_resp_prod_copy)].req.gref; + netif->rx_resp_prod_copy++; + gop++; +#else + mcl->op = __HYPERVISOR_mmuext_op; + mcl->args[0] = (unsigned long)mmuext; + mcl->args[1] = 1; + mcl->args[2] = 0; + mcl->args[3] = netif->domid; + mcl++; + + mmuext->cmd = MMUEXT_REASSIGN_PAGE; + mmuext->arg1.mfn = old_mfn; + mmuext++; +#endif + mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) | + MMU_MACHPHYS_UPDATE; + mmu->val = __pa(vdata) >> PAGE_SHIFT; + mmu++; + + __skb_queue_tail(&rxq, skb); #ifdef DEBUG_GRANT - dump_packet('a', old_mfn, vdata); -#endif - /* Filled the batch queue? */ - if ( (mcl - rx_mcl) == ARRAY_SIZE(rx_mcl) ) - break; - } - - if ( mcl == rx_mcl ) - return; - - mcl->op = __HYPERVISOR_mmu_update; - mcl->args[0] = (unsigned long)rx_mmu; - mcl->args[1] = mmu - rx_mmu; - mcl->args[2] = 0; - mcl->args[3] = DOMID_SELF; - mcl++; - -#ifdef CONFIG_XEN_NETDEV_GRANT - mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; -#else - mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; -#endif - if ( unlikely(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0) ) - BUG(); - - mcl = rx_mcl; -#ifdef CONFIG_XEN_NETDEV_GRANT - if(HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, - gop - grant_rx_op)) { - /* - ** The other side has given us a bad grant ref, or has no headroom, - ** or has gone away. Unfortunately the current grant table code - ** doesn't inform us which is the case, so not much we can do. - */ - DPRINTK("net_rx: transfer to DOM%u failed; dropping (up to) %d " - "packets.\n", grant_rx_op[0].domid, gop - grant_rx_op); - } - gop = grant_rx_op; -#else - mmuext = rx_mmuext; -#endif - while ( (skb = __skb_dequeue(&rxq)) != NULL ) - { - netif = netdev_priv(skb->dev); - size = skb->tail - skb->data; - - /* Rederive the machine addresses. */ - new_mfn = mcl[0].args[1] >> PAGE_SHIFT; -#ifdef CONFIG_XEN_NETDEV_GRANT - old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */ -#else - old_mfn = mmuext[0].arg1.mfn; -#endif - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->frag_list = NULL; - - netif->stats.tx_bytes += size; - netif->stats.tx_packets++; - - /* The update_va_mapping() must not fail. */ - BUG_ON(mcl[0].result != 0); - - /* Check the reassignment error code. */ - status = NETIF_RSP_OKAY; -#ifdef CONFIG_XEN_NETDEV_GRANT - if(gop->status != 0) { - DPRINTK("Bad status %d from grant transfer to DOM%u\n", - gop->status, netif->domid); - /* XXX SMH: should free 'old_mfn' here */ - status = NETIF_RSP_ERROR; - } -#else - if ( unlikely(mcl[1].result != 0) ) - { - DPRINTK("Failed MMU update transferring to DOM%u\n", netif->domid); - free_mfn(old_mfn); - status = NETIF_RSP_ERROR; - } -#endif - evtchn = netif->evtchn; - id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id; - if ( make_rx_response(netif, id, status, - (old_mfn << PAGE_SHIFT) | /* XXX */ - ((unsigned long)skb->data & ~PAGE_MASK), - size, skb->proto_csum_valid) && - (rx_notify[evtchn] == 0) ) - { - rx_notify[evtchn] = 1; - notify_list[notify_nr++] = evtchn; - } - - netif_put(netif); - dev_kfree_skb(skb); -#ifdef CONFIG_XEN_NETDEV_GRANT - mcl++; - gop++; -#else - mcl += 2; - mmuext += 1; -#endif - } - - while ( notify_nr != 0 ) - { - evtchn = notify_list[--notify_nr]; - rx_notify[evtchn] = 0; - notify_via_evtchn(evtchn); - } - - out: - /* More work to do? */ - if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) ) - tasklet_schedule(&net_rx_tasklet); + dump_packet('a', old_mfn, vdata); +#endif + /* Filled the batch queue? */ + if ((mcl - rx_mcl) == ARRAY_SIZE(rx_mcl)) + break; + } + + if (mcl == rx_mcl) + return; + + mcl->op = __HYPERVISOR_mmu_update; + mcl->args[0] = (unsigned long)rx_mmu; + mcl->args[1] = mmu - rx_mmu; + mcl->args[2] = 0; + mcl->args[3] = DOMID_SELF; + mcl++; + +#ifdef CONFIG_XEN_NETDEV_GRANT + mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; +#else + mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; +#endif + BUG_ON(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0); + + mcl = rx_mcl; +#ifdef CONFIG_XEN_NETDEV_GRANT + if(HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, + gop - grant_rx_op)) { + /* + * The other side has given us a bad grant ref, or has no + * headroom, or has gone away. Unfortunately the current grant + * table code doesn't inform us which is the case, so not much + * we can do. + */ + DPRINTK("net_rx: transfer to DOM%u failed; dropping (up to) " + "%d packets.\n", + grant_rx_op[0].domid, gop - grant_rx_op); + } + gop = grant_rx_op; +#else + mmuext = rx_mmuext; +#endif + while ((skb = __skb_dequeue(&rxq)) != NULL) { + netif = netdev_priv(skb->dev); + size = skb->tail - skb->data; + + /* Rederive the machine addresses. */ + new_mfn = mcl[0].args[1] >> PAGE_SHIFT; +#ifdef CONFIG_XEN_NETDEV_GRANT + old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */ +#else + old_mfn = mmuext[0].arg1.mfn; +#endif + atomic_set(&(skb_shinfo(skb)->dataref), 1); + skb_shinfo(skb)->nr_frags = 0; + skb_shinfo(skb)->frag_list = NULL; + + netif->stats.tx_bytes += size; + netif->stats.tx_packets++; + + /* The update_va_mapping() must not fail. */ + BUG_ON(mcl[0].result != 0); + + /* Check the reassignment error code. */ + status = NETIF_RSP_OKAY; +#ifdef CONFIG_XEN_NETDEV_GRANT + if(gop->status != 0) { + DPRINTK("Bad status %d from grant transfer to DOM%u\n", + gop->status, netif->domid); + /* XXX SMH: should free 'old_mfn' here */ + status = NETIF_RSP_ERROR; + } +#else + if (unlikely(mcl[1].result != 0)) { + DPRINTK("Failed MMU update transferring to DOM%u\n", + netif->domid); + free_mfn(old_mfn); + status = NETIF_RSP_ERROR; + } +#endif + evtchn = netif->evtchn; + id = netif->rx->ring[ + MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id; + if (make_rx_response(netif, id, status, + (old_mfn << PAGE_SHIFT) | /* XXX */ + ((unsigned long)skb->data & ~PAGE_MASK), + size, skb->proto_csum_valid) && + (rx_notify[evtchn] == 0)) { + rx_notify[evtchn] = 1; + notify_list[notify_nr++] = evtchn; + } + + netif_put(netif); + dev_kfree_skb(skb); +#ifdef CONFIG_XEN_NETDEV_GRANT + mcl++; + gop++; +#else + mcl += 2; + mmuext += 1; +#endif + } + + while (notify_nr != 0) { + evtchn = notify_list[--notify_nr]; + rx_notify[evtchn] = 0; + notify_via_evtchn(evtchn); + } + + /* More work to do? */ + if (!skb_queue_empty(&rx_queue) && !timer_pending(&net_timer)) + tasklet_schedule(&net_rx_tasklet); #if 0 - else - xen_network_done_notify(); + else + xen_network_done_notify(); #endif } static void net_alarm(unsigned long unused) { - tasklet_schedule(&net_rx_tasklet); + tasklet_schedule(&net_rx_tasklet); } struct net_device_stats *netif_be_get_stats(struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - return &netif->stats; + netif_t *netif = netdev_priv(dev); + return &netif->stats; } static int __on_net_schedule_list(netif_t *netif) { - return netif->list.next != NULL; + return netif->list.next != NULL; } static void remove_from_net_schedule_list(netif_t *netif) { - spin_lock_irq(&net_schedule_list_lock); - if ( likely(__on_net_schedule_list(netif)) ) - { - list_del(&netif->list); - netif->list.next = NULL; - netif_put(netif); - } - spin_unlock_irq(&net_schedule_list_lock); + spin_lock_irq(&net_schedule_list_lock); + if (likely(__on_net_schedule_list(netif))) { + list_del(&netif->list); + netif->list.next = NULL; + netif_put(netif); + } + spin_unlock_irq(&net_schedule_list_lock); } static void add_to_net_schedule_list_tail(netif_t *netif) { - if ( __on_net_schedule_list(netif) ) - return; - - spin_lock_irq(&net_schedule_list_lock); - if ( !__on_net_schedule_list(netif) && netif->active ) - { - list_add_tail(&netif->list, &net_schedule_list); - netif_get(netif); - } - spin_unlock_irq(&net_schedule_list_lock); + if (__on_net_schedule_list(netif)) + return; + + spin_lock_irq(&net_schedule_list_lock); + if (!__on_net_schedule_list(netif) && netif->active) { + list_add_tail(&netif->list, &net_schedule_list); + netif_get(netif); + } + spin_unlock_irq(&net_schedule_list_lock); } void netif_schedule_work(netif_t *netif) { - if ( (netif->tx_req_cons != netif->tx->req_prod) && - ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) ) - { - add_to_net_schedule_list_tail(netif); - maybe_schedule_tx_action(); - } + if ((netif->tx_req_cons != netif->tx->req_prod) && + ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE)) { + add_to_net_schedule_list_tail(netif); + maybe_schedule_tx_action(); + } } void netif_deschedule_work(netif_t *netif) { - remove_from_net_schedule_list(netif); + remove_from_net_schedule_list(netif); } static void tx_credit_callback(unsigned long data) { - netif_t *netif = (netif_t *)data; - netif->remaining_credit = netif->credit_bytes; - netif_schedule_work(netif); + netif_t *netif = (netif_t *)data; + netif->remaining_credit = netif->credit_bytes; + netif_schedule_work(netif); } inline static void net_tx_action_dealloc(void) { #ifdef CONFIG_XEN_NETDEV_GRANT - gnttab_unmap_grant_ref_t *gop; -#else - multicall_entry_t *mcl; -#endif - u16 pending_idx; - PEND_RING_IDX dc, dp; - netif_t *netif; - - dc = dealloc_cons; - dp = dealloc_prod; - -#ifdef CONFIG_XEN_NETDEV_GRANT - /* - * Free up any grants we have finished using - */ - gop = tx_unmap_ops; - while ( dc != dp ) - { - pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; - gop->host_addr = MMAP_VADDR(pending_idx); - gop->dev_bus_addr = 0; - gop->handle = grant_tx_ref[pending_idx]; - grant_tx_ref[pending_idx] = GRANT_INVALID_REF; - gop++; - } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops)); -#else - mcl = tx_mcl; - while ( dc != dp ) - { - pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; - MULTI_update_va_mapping(mcl, MMAP_VADDR(pending_idx), - __pte(0), 0); - mcl++; - } - - mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; - if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) ) - BUG(); - - mcl = tx_mcl; -#endif - while ( dealloc_cons != dp ) - { + gnttab_unmap_grant_ref_t *gop; +#else + multicall_entry_t *mcl; +#endif + u16 pending_idx; + PEND_RING_IDX dc, dp; + netif_t *netif; + + dc = dealloc_cons; + dp = dealloc_prod; + +#ifdef CONFIG_XEN_NETDEV_GRANT + /* + * Free up any grants we have finished using + */ + gop = tx_unmap_ops; + while (dc != dp) { + pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; + gop->host_addr = MMAP_VADDR(pending_idx); + gop->dev_bus_addr = 0; + gop->handle = grant_tx_ref[pending_idx]; + grant_tx_ref[pending_idx] = GRANT_INVALID_REF; + gop++; + } + BUG_ON(HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops)); +#else + mcl = tx_mcl; + while (dc != dp) { + pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; + MULTI_update_va_mapping(mcl, MMAP_VADDR(pending_idx), + __pte(0), 0); + mcl++; + } + + mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; + BUG_ON(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0); + + mcl = tx_mcl; +#endif + while (dealloc_cons != dp) { #ifndef CONFIG_XEN_NETDEV_GRANT - /* The update_va_mapping() must not fail. */ - BUG_ON(mcl[0].result != 0); -#endif - - pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; - - netif = pending_tx_info[pending_idx].netif; - - make_tx_response(netif, pending_tx_info[pending_idx].req.id, - NETIF_RSP_OKAY); + /* The update_va_mapping() must not fail. */ + BUG_ON(mcl[0].result != 0); +#endif + + pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; + + netif = pending_tx_info[pending_idx].netif; + + make_tx_response(netif, pending_tx_info[pending_idx].req.id, + NETIF_RSP_OKAY); - pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; - - /* - * Scheduling checks must happen after the above response is posted. - * This avoids a possible race with a guest OS on another CPU if that - * guest is testing against 'resp_prod' when deciding whether to notify - * us when it queues additional packets. - */ - mb(); - if ( (netif->tx_req_cons != netif->tx->req_prod) && - ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) ) - add_to_net_schedule_list_tail(netif); + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; + + /* + * Scheduling checks must happen after the above response is + * posted. This avoids a possible race with a guest OS on + * another CPU if that guest is testing against 'resp_prod' + * when deciding whether to notify us when it queues additional + * packets. + */ + mb(); + if ((netif->tx_req_cons != netif->tx->req_prod) && + ((netif->tx_req_cons-netif->tx_resp_prod) != + NETIF_TX_RING_SIZE)) + add_to_net_schedule_list_tail(netif); - netif_put(netif); + netif_put(netif); #ifndef CONFIG_XEN_NETDEV_GRANT - mcl++; -#endif - } - + mcl++; +#endif + } } /* Called after netfront has transmitted */ static void net_tx_action(unsigned long unused) { - struct list_head *ent; - struct sk_buff *skb; - netif_t *netif; - netif_tx_request_t txreq; - u16 pending_idx; - NETIF_RING_IDX i; -#ifdef CONFIG_XEN_NETDEV_GRANT - gnttab_map_grant_ref_t *mop; -#else - multicall_entry_t *mcl; -#endif - unsigned int data_len; - - if ( dealloc_cons != dealloc_prod ) - net_tx_action_dealloc(); - -#ifdef CONFIG_XEN_NETDEV_GRANT - mop = tx_map_ops; -#else - mcl = tx_mcl; -#endif - while ( (NR_PENDING_REQS < MAX_PENDING_REQS) && - !list_empty(&net_schedule_list) ) - { - /* Get a netif from the list with work to do. */ - ent = net_schedule_list.next; - netif = list_entry(ent, netif_t, list); - netif_get(netif); - remove_from_net_schedule_list(netif); - - /* Work to do? */ - i = netif->tx_req_cons; - if ( (i == netif->tx->req_prod) || - ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE) ) - { - netif_put(netif); - continue; - } - - rmb(); /* Ensure that we see the request before we copy it. */ - memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req, - sizeof(txreq)); - /* Credit-based scheduling. */ - if ( txreq.size > netif->remaining_credit ) - { - unsigned long now = jiffies; - unsigned long next_credit = - netif->credit_timeout.expires + - msecs_to_jiffies(netif->credit_usec / 1000); - - /* Timer could already be pending in some rare cases. */ - if ( timer_pending(&netif->credit_timeout) ) - break; - - /* Already passed the point at which we can replenish credit? */ - if ( time_after_eq(now, next_credit) ) - { - netif->credit_timeout.expires = now; - netif->remaining_credit = netif->credit_bytes; - } - - /* Still too big to send right now? Then set a timer callback. */ - if ( txreq.size > netif->remaining_credit ) - { - netif->remaining_credit = 0; - netif->credit_timeout.expires = next_credit; - netif->credit_timeout.data = (unsigned long)netif; - netif->credit_timeout.function = tx_credit_callback; - add_timer_on(&netif->credit_timeout, smp_processor_id()); - break; - } - } - netif->remaining_credit -= txreq.size; - - /* - * Why the barrier? It ensures that the frontend sees updated req_cons - * before we check for more work to schedule. - */ - netif->tx->req_cons = ++netif->tx_req_cons; - mb(); - - netif_schedule_work(netif); - - if ( unlikely(txreq.size < ETH_HLEN) || - unlikely(txreq.size > ETH_FRAME_LEN) ) - { - DPRINTK("Bad packet size: %d\n", txreq.size); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - continue; - } - - /* No crossing a page boundary as the payload mustn't fragment. */ - if ( unlikely(((txreq.addr & ~PAGE_MASK) + txreq.size) >= PAGE_SIZE) ) - { - DPRINTK("txreq.addr: %lx, size: %u, end: %lu\n", - txreq.addr, txreq.size, - (txreq.addr &~PAGE_MASK) + txreq.size); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - continue; - } - - pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; - - data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size; - - if ( unlikely((skb = alloc_skb(data_len+16, GFP_ATOMIC)) == NULL) ) - { - DPRINTK("Can't allocate a skb in start_xmit.\n"); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - break; - } - - /* Packets passed to netif_rx() must have some headroom. */ - skb_reserve(skb, 16); -#ifdef CONFIG_XEN_NETDEV_GRANT - mop->host_addr = MMAP_VADDR(pending_idx); - mop->dom = netif->domid; - mop->ref = txreq.addr >> PAGE_SHIFT; - mop->flags = GNTMAP_host_map | GNTMAP_readonly; - mop++; -#else - MULTI_update_va_mapping_otherdomain( - mcl, MMAP_VADDR(pending_idx), - pfn_pte_ma(txreq.addr >> PAGE_SHIFT, PAGE_KERNEL), - 0, netif->domid); - - mcl++; -#endif - - memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq)); - pending_tx_info[pending_idx].netif = netif; - *((u16 *)skb->data) = pending_idx; - - __skb_queue_tail(&tx_queue, skb); - - pending_cons++; - -#ifdef CONFIG_XEN_NETDEV_GRANT - if ( (mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops) ) - break; -#else - /* Filled the batch queue? */ - if ( (mcl - tx_mcl) == ARRAY_SIZE(tx_mcl) ) - break; -#endif - } - -#ifdef CONFIG_XEN_NETDEV_GRANT - if ( mop == tx_map_ops ) - return; - - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops)); - - mop = tx_map_ops; -#else - if ( mcl == tx_mcl ) - return; - - BUG_ON(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0); - - mcl = tx_mcl; -#endif - while ( (skb = __skb_dequeue(&tx_queue)) != NULL ) - { - pending_idx = *((u16 *)skb->data); - netif = pending_tx_info[pending_idx].netif; - memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq)); - - /* Check the remap error code. */ -#ifdef CONFIG_XEN_NETDEV_GRANT - if ( unlikely(mop->handle < 0) ) - { - printk(KERN_ALERT "#### netback grant fails\n"); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - kfree_skb(skb); - mop++; - pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; - continue; - } - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] = - FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT); - grant_tx_ref[pending_idx] = mop->handle; -#else - if ( unlikely(mcl[0].result != 0) ) - { - DPRINTK("Bad page frame\n"); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - kfree_skb(skb); - mcl++; - pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; - continue; - } - - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] = - FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT); -#endif - - data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size; - - __skb_put(skb, data_len); - memcpy(skb->data, - (void *)(MMAP_VADDR(pending_idx)|(txreq.addr&~PAGE_MASK)), - data_len); - if ( data_len < txreq.size ) - { - /* Append the packet payload as a fragment. */ - skb_shinfo(skb)->frags[0].page = - virt_to_page(MMAP_VADDR(pending_idx)); - skb_shinfo(skb)->frags[0].size = txreq.size - data_len; - skb_shinfo(skb)->frags[0].page_offset = - (txreq.addr + data_len) & ~PAGE_MASK; - skb_shinfo(skb)->nr_frags = 1; - } - else - { - /* Schedule a response immediately. */ - netif_idx_release(pending_idx); - } - - skb->data_len = txreq.size - data_len; - skb->len += skb->data_len; - - skb->dev = netif->dev; - skb->protocol = eth_type_trans(skb, skb->dev); - - /* No checking needed on localhost, but remember the field is blank. */ - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->proto_csum_valid = 1; - skb->proto_csum_blank = txreq.csum_blank; - - netif->stats.rx_bytes += txreq.size; - netif->stats.rx_packets++; - - netif_rx(skb); - netif->dev->last_rx = jiffies; - -#ifdef CONFIG_XEN_NETDEV_GRANT - mop++; -#else - mcl++; -#endif - } + struct list_head *ent; + struct sk_buff *skb; + netif_t *netif; + netif_tx_request_t txreq; + u16 pending_idx; + NETIF_RING_IDX i; +#ifdef CONFIG_XEN_NETDEV_GRANT + gnttab_map_grant_ref_t *mop; +#else + multicall_entry_t *mcl; +#endif + unsigned int data_len; + + if (dealloc_cons != dealloc_prod) + net_tx_action_dealloc(); + +#ifdef CONFIG_XEN_NETDEV_GRANT + mop = tx_map_ops; +#else + mcl = tx_mcl; +#endif + while ((NR_PENDING_REQS < MAX_PENDING_REQS) && + !list_empty(&net_schedule_list)) { + /* Get a netif from the list with work to do. */ + ent = net_schedule_list.next; + netif = list_entry(ent, netif_t, list); + netif_get(netif); + remove_from_net_schedule_list(netif); + + /* Work to do? */ + i = netif->tx_req_cons; + if ((i == netif->tx->req_prod) || + ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE)) { + netif_put(netif); + continue; + } + + rmb(); /* Ensure that we see the request before we copy it. */ + memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req, + sizeof(txreq)); + /* Credit-based scheduling. */ + if (txreq.size > netif->remaining_credit) { + unsigned long now = jiffies; + unsigned long next_credit = + netif->credit_timeout.expires + + msecs_to_jiffies(netif->credit_usec / 1000); + + /* Timer could already be pending in rare cases. */ + if (timer_pending(&netif->credit_timeout)) + break; + + /* Passed the point where we can replenish credit? */ + if (time_after_eq(now, next_credit)) { + netif->credit_timeout.expires = now; + netif->remaining_credit = netif->credit_bytes; + } + + /* Still too big to send right now? Set a callback. */ + if (txreq.size > netif->remaining_credit) { + netif->remaining_credit = 0; + netif->credit_timeout.expires = + next_credit; + netif->credit_timeout.data = + (unsigned long)netif; + netif->credit_timeout.function = + tx_credit_callback; + add_timer_on(&netif->credit_timeout, + smp_processor_id()); + break; + } + } + netif->remaining_credit -= txreq.size; + + /* + * Why the barrier? It ensures that the frontend sees updated + * req_cons before we check for more work to schedule. + */ + netif->tx->req_cons = ++netif->tx_req_cons; + mb(); + + netif_schedule_work(netif); + + if (unlikely(txreq.size < ETH_HLEN) || + unlikely(txreq.size > ETH_FRAME_LEN)) { + DPRINTK("Bad packet size: %d\n", txreq.size); + make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); + netif_put(netif); + continue; + } + + /* No crossing a page as the payload mustn't fragment. */ + if (unlikely(((txreq.addr & ~PAGE_MASK) + txreq.size) >= + PAGE_SIZE)) { + DPRINTK("txreq.addr: %lx, size: %u, end: %lu\n", + txreq.addr, txreq.size, + (txreq.addr &~PAGE_MASK) + txreq.size); + make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); + netif_put(netif); + continue; + } + + pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; + + data_len = (txreq.size > PKT_PROT_LEN) ? + PKT_PROT_LEN : txreq.size; + + skb = alloc_skb(data_len+16, GFP_ATOMIC); + if (unlikely(skb == NULL)) { + DPRINTK("Can't allocate a skb in start_xmit.\n"); + make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); + netif_put(netif); + break; + } + + /* Packets passed to netif_rx() must have some headroom. */ + skb_reserve(skb, 16); +#ifdef CONFIG_XEN_NETDEV_GRANT + mop->host_addr = MMAP_VADDR(pending_idx); + mop->dom = netif->domid; + mop->ref = txreq.addr >> PAGE_SHIFT; + mop->flags = GNTMAP_host_map | GNTMAP_readonly; + mop++; +#else + MULTI_update_va_mapping_otherdomain( + mcl, MMAP_VADDR(pending_idx), + pfn_pte_ma(txreq.addr >> PAGE_SHIFT, PAGE_KERNEL), + 0, netif->domid); + + mcl++; +#endif + + memcpy(&pending_tx_info[pending_idx].req, + &txreq, sizeof(txreq)); + pending_tx_info[pending_idx].netif = netif; + *((u16 *)skb->data) = pending_idx; + + __skb_queue_tail(&tx_queue, skb); + + pending_cons++; + +#ifdef CONFIG_XEN_NETDEV_GRANT + if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops)) + break; +#else + /* Filled the batch queue? */ + if ((mcl - tx_mcl) == ARRAY_SIZE(tx_mcl)) + break; +#endif + } + +#ifdef CONFIG_XEN_NETDEV_GRANT + if (mop == tx_map_ops) + return; + + BUG_ON(HYPERVISOR_grant_table_op( + GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops)); + + mop = tx_map_ops; +#else + if (mcl == tx_mcl) + return; + + BUG_ON(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0); + + mcl = tx_mcl; +#endif + while ((skb = __skb_dequeue(&tx_queue)) != NULL) { + pending_idx = *((u16 *)skb->data); + netif = pending_tx_info[pending_idx].netif; + memcpy(&txreq, &pending_tx_info[pending_idx].req, + sizeof(txreq)); + + /* Check the remap error code. */ +#ifdef CONFIG_XEN_NETDEV_GRANT + if (unlikely(mop->handle < 0)) { + printk(KERN_ALERT "#### netback grant fails\n"); + make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); + netif_put(netif); + kfree_skb(skb); + mop++; + pending_ring[MASK_PEND_IDX(pending_prod++)] = + pending_idx; + continue; + } + phys_to_machine_mapping[ + __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] = + FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT); + grant_tx_ref[pending_idx] = mop->handle; +#else + if (unlikely(mcl[0].result != 0)) { + DPRINTK("Bad page frame\n"); + make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); + netif_put(netif); + kfree_skb(skb); + mcl++; + pending_ring[MASK_PEND_IDX(pending_prod++)] = + pending_idx; + continue; + } + + phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> + PAGE_SHIFT] = + FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT); +#endif + + data_len = (txreq.size > PKT_PROT_LEN) ? + PKT_PROT_LEN : txreq.size; + + __skb_put(skb, data_len); + memcpy(skb->data, + (void *)(MMAP_VADDR(pending_idx)| + (txreq.addr&~PAGE_MASK)), + data_len); + if (data_len < txreq.size) { + /* Append the packet payload as a fragment. */ + skb_shinfo(skb)->frags[0].page = + virt_to_page(MMAP_VADDR(pending_idx)); + skb_shinfo(skb)->frags[0].size = + txreq.size - data_len; + skb_shinfo(skb)->frags[0].page_offset = + (txreq.addr + data_len) & ~PAGE_MASK; + skb_shinfo(skb)->nr_frags = 1; + } else { + /* Schedule a response immediately. */ + netif_idx_release(pending_idx); + } + + skb->data_len = txreq.size - data_len; + skb->len += skb->data_len; + + skb->dev = netif->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + + /* + * No checking needed on localhost, but remember the field is + * blank. + */ + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->proto_csum_valid = 1; + skb->proto_csum_blank = txreq.csum_blank; + + netif->stats.rx_bytes += txreq.size; + netif->stats.rx_packets++; + + netif_rx(skb); + netif->dev->last_rx = jiffies; + +#ifdef CONFIG_XEN_NETDEV_GRANT + mop++; +#else + mcl++; +#endif + } } static void netif_idx_release(u16 pending_idx) { - static spinlock_t _lock = SPIN_LOCK_UNLOCKED; - unsigned long flags; - - spin_lock_irqsave(&_lock, flags); - dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx; - spin_unlock_irqrestore(&_lock, flags); - - tasklet_schedule(&net_tx_tasklet); + static spinlock_t _lock = SPIN_LOCK_UNLOCKED; + unsigned long flags; + + spin_lock_irqsave(&_lock, flags); + dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx; + spin_unlock_irqrestore(&_lock, flags); + + tasklet_schedule(&net_tx_tasklet); } static void netif_page_release(struct page *page) { - u16 pending_idx = page - virt_to_page(mmap_vstart); - - /* Ready for next use. */ - set_page_count(page, 1); - - netif_idx_release(pending_idx); + u16 pending_idx = page - virt_to_page(mmap_vstart); + + /* Ready for next use. */ + set_page_count(page, 1); + + netif_idx_release(pending_idx); } irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) { - netif_t *netif = dev_id; - if ( tx_work_exists(netif) ) - { - add_to_net_schedule_list_tail(netif); - maybe_schedule_tx_action(); - } - return IRQ_HANDLED; + netif_t *netif = dev_id; + if (tx_work_exists(netif)) { + add_to_net_schedule_list_tail(netif); + maybe_schedule_tx_action(); + } + return IRQ_HANDLED; } static void make_tx_response(netif_t *netif, u16 id, s8 st) { - NETIF_RING_IDX i = netif->tx_resp_prod; - netif_tx_response_t *resp; - - resp = &netif->tx->ring[MASK_NETIF_TX_IDX(i)].resp; - resp->id = id; - resp->status = st; - wmb(); - netif->tx->resp_prod = netif->tx_resp_prod = ++i; - - mb(); /* Update producer before checking event threshold. */ - if ( i == netif->tx->event ) - notify_via_evtchn(netif->evtchn); + NETIF_RING_IDX i = netif->tx_resp_prod; + netif_tx_response_t *resp; + + resp = &netif->tx->ring[MASK_NETIF_TX_IDX(i)].resp; + resp->id = id; + resp->status = st; + wmb(); + netif->tx->resp_prod = netif->tx_resp_prod = ++i; + + mb(); /* Update producer before checking event threshold. */ + if (i == netif->tx->event) + notify_via_evtchn(netif->evtchn); } static int make_rx_response(netif_t *netif, @@ -882,110 +878,120 @@ u16 size, u16 csum_valid) { - NETIF_RING_IDX i = netif->rx_resp_prod; - netif_rx_response_t *resp; - - resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp; - resp->addr = addr; - resp->csum_valid = csum_valid; - resp->id = id; - resp->status = (s16)size; - if ( st < 0 ) - resp->status = (s16)st; - wmb(); - netif->rx->resp_prod = netif->rx_resp_prod = ++i; - - mb(); /* Update producer before checking event threshold. */ - return (i == netif->rx->event); + NETIF_RING_IDX i = netif->rx_resp_prod; + netif_rx_response_t *resp; + + resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp; + resp->addr = addr; + resp->csum_valid = csum_valid; + resp->id = id; + resp->status = (s16)size; + if (st < 0) + resp->status = (s16)st; + wmb(); + netif->rx->resp_prod = netif->rx_resp_prod = ++i; + + mb(); /* Update producer before checking event threshold. */ + return (i == netif->rx->event); } static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs) { - struct list_head *ent; - netif_t *netif; - int i = 0; - - printk(KERN_ALERT "netif_schedule_list:\n"); - spin_lock_irq(&net_schedule_list_lock); - - list_for_each ( ent, &net_schedule_list ) - { - netif = list_entry(ent, netif_t, list); - printk(KERN_ALERT " %d: private(rx_req_cons=%08x rx_resp_prod=%08x\n", - i, netif->rx_req_cons, netif->rx_resp_prod); - printk(KERN_ALERT " tx_req_cons=%08x tx_resp_prod=%08x)\n", - netif->tx_req_cons, netif->tx_resp_prod); - printk(KERN_ALERT " shared(rx_req_prod=%08x rx_resp_prod=%08x\n", - netif->rx->req_prod, netif->rx->resp_prod); - printk(KERN_ALERT " rx_event=%08x tx_req_prod=%08x\n", - netif->rx->event, netif->tx->req_prod); - printk(KERN_ALERT " tx_resp_prod=%08x, tx_event=%08x)\n", - netif->tx->resp_prod, netif->tx->event); - i++; - } - - spin_unlock_irq(&net_schedule_list_lock); - printk(KERN_ALERT " ** End of netif_schedule_list **\n"); - - return IRQ_HANDLED; + struct list_head *ent; + netif_t *netif; + int i = 0; + + printk(KERN_ALERT "netif_schedule_list:\n"); + spin_lock_irq(&net_schedule_list_lock); + + list_for_each (ent, &net_schedule_list) { + netif = list_entry(ent, netif_t, list); + printk(KERN_ALERT " %d: private(rx_req_cons=%08x " + "rx_resp_prod=%08x\n", + i, netif->rx_req_cons, netif->rx_resp_prod); + printk(KERN_ALERT " tx_req_cons=%08x tx_resp_prod=%08x)\n", + netif->tx_req_cons, netif->tx_resp_prod); + printk(KERN_ALERT " shared(rx_req_prod=%08x " + "rx_resp_prod=%08x\n", + netif->rx->req_prod, netif->rx->resp_prod); + printk(KERN_ALERT " rx_event=%08x tx_req_prod=%08x\n", + netif->rx->event, netif->tx->req_prod); + printk(KERN_ALERT " tx_resp_prod=%08x, tx_event=%08x)\n", + netif->tx->resp_prod, netif->tx->event); + i++; + } + + spin_unlock_irq(&net_schedule_list_lock); + printk(KERN_ALERT " ** End of netif_schedule_list **\n"); + + return IRQ_HANDLED; } static int __init netback_init(void) { - int i; - struct page *page; - - if ( !(xen_start_info->flags & SIF_NET_BE_DOMAIN) && - !(xen_start_info->flags & SIF_INITDOMAIN) ) - return 0; - - IPRINTK("Initialising Xen netif backend.\n"); -#ifdef CONFIG_XEN_NETDEV_GRANT - IPRINTK("Using grant tables.\n"); -#endif - - /* We can increase reservation by this much in net_rx_action(). */ - balloon_update_driver_allowance(NETIF_RX_RING_SIZE); - - skb_queue_head_init(&rx_queue); - skb_queue_head_init(&tx_queue); - - init_timer(&net_timer); - net_timer.data = 0; - net_timer.function = net_alarm; + int i; + struct page *page; + + if (!(xen_start_info->flags & SIF_NET_BE_DOMAIN) && + !(xen_start_info->flags & SIF_INITDOMAIN)) + return 0; + + IPRINTK("Initialising Xen netif backend.\n"); +#ifdef CONFIG_XEN_NETDEV_GRANT + IPRINTK("Using grant tables.\n"); +#endif + + /* We can increase reservation by this much in net_rx_action(). */ + balloon_update_driver_allowance(NETIF_RX_RING_SIZE); + + skb_queue_head_init(&rx_queue); + skb_queue_head_init(&tx_queue); + + init_timer(&net_timer); + net_timer.data = 0; + net_timer.function = net_alarm; - page = balloon_alloc_empty_page_range(MAX_PENDING_REQS); - BUG_ON(page == NULL); - mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); - - for ( i = 0; i < MAX_PENDING_REQS; i++ ) - { - page = virt_to_page(MMAP_VADDR(i)); - set_page_count(page, 1); - SetPageForeign(page, netif_page_release); - } - - pending_cons = 0; - pending_prod = MAX_PENDING_REQS; - for ( i = 0; i < MAX_PENDING_REQS; i++ ) - pending_ring[i] = i; - - spin_lock_init(&net_schedule_list_lock); - INIT_LIST_HEAD(&net_schedule_list); - - netif_xenbus_init(); - - (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG), - netif_be_dbg, SA_SHIRQ, - "net-be-dbg", &netif_be_dbg); - - return 0; + page = balloon_alloc_empty_page_range(MAX_PENDING_REQS); + BUG_ON(page == NULL); + mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); + + for (i = 0; i < MAX_PENDING_REQS; i++) { + page = virt_to_page(MMAP_VADDR(i)); + set_page_count(page, 1); + SetPageForeign(page, netif_page_release); + } + + pending_cons = 0; + pending_prod = MAX_PENDING_REQS; + for (i = 0; i < MAX_PENDING_REQS; i++) + pending_ring[i] = i; + + spin_lock_init(&net_schedule_list_lock); + INIT_LIST_HEAD(&net_schedule_list); + + netif_xenbus_init(); + + (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG), + netif_be_dbg, SA_SHIRQ, + "net-be-dbg", &netif_be_dbg); + + return 0; } static void netback_cleanup(void) { - BUG(); + BUG(); } module_init(netback_init); module_exit(netback_cleanup); + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -r 8bb3f2567b8c -r 7fbaf67a0af5 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Sep 16 13:06:49 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Sep 16 13:27:01 2005 @@ -294,3 +294,13 @@ { xenbus_register_backend(&netback); } + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |