diff options
author | Wei Liu <wei.liu2@citrix.com> | 2014-06-04 10:30:42 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-04 14:48:16 -0700 |
commit | e9ce7cb6b107407e4798e8905b18ad8b642766f6 (patch) | |
tree | dd99d31fa4f2bae0e836c99a811e5de4e1202567 /drivers/net/xen-netback/common.h | |
parent | a55d9766cecf2b1b9af4fcf93b2d41b71e599c76 (diff) |
xen-netback: Factor queue-specific data into queue struct
In preparation for multi-queue support in xen-netback, move the
queue-specific data from struct xenvif into struct xenvif_queue, and
update the rest of the code to use this.
Also adds loops over queues where appropriate, even though only one is
configured at this point, and uses alloc_netdev_mq() and the
corresponding multi-queue netif wake/start/stop functions in preparation
for multiple active queues.
Finally, implements a trivial queue selection function suitable for
ndo_select_queue, which simply returns 0 for a single queue and uses
skb_get_hash() to compute the queue index otherwise.
Signed-off-by: Andrew J. Bennieston <andrew.bennieston@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback/common.h')
-rw-r--r-- | drivers/net/xen-netback/common.h | 102 |
1 files changed, 69 insertions, 33 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 2c283d693330..b6885cfcc7df 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -99,22 +99,43 @@ struct xenvif_rx_meta { */ #define XEN_NETBK_LEGACY_SLOTS_MAX XEN_NETIF_NR_SLOTS_MIN -struct xenvif { - /* Unique identifier for this interface. */ - domid_t domid; - unsigned int handle; +/* Queue name is interface name with "-qNNN" appended */ +#define QUEUE_NAME_SIZE (IFNAMSIZ + 5) - /* Is this interface disabled? True when backend discovers - * frontend is rogue. +/* IRQ name is queue name with "-tx" or "-rx" appended */ +#define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) + +struct xenvif; + +struct xenvif_stats { + /* Stats fields to be updated per-queue. + * A subset of struct net_device_stats that contains only the + * fields that are updated in netback.c for each queue. */ - bool disabled; + unsigned int rx_bytes; + unsigned int rx_packets; + unsigned int tx_bytes; + unsigned int tx_packets; + + /* Additional stats used by xenvif */ + unsigned long rx_gso_checksum_fixup; + unsigned long tx_zerocopy_sent; + unsigned long tx_zerocopy_success; + unsigned long tx_zerocopy_fail; + unsigned long tx_frag_overflow; +}; + +struct xenvif_queue { /* Per-queue data for xenvif */ + unsigned int id; /* Queue ID, 0-based */ + char name[QUEUE_NAME_SIZE]; /* DEVNAME-qN */ + struct xenvif *vif; /* Parent VIF */ /* Use NAPI for guest TX */ struct napi_struct napi; /* When feature-split-event-channels = 0, tx_irq = rx_irq. */ unsigned int tx_irq; /* Only used when feature-split-event-channels = 1 */ - char tx_irq_name[IFNAMSIZ+4]; /* DEVNAME-tx */ + char tx_irq_name[IRQ_NAME_SIZE]; /* DEVNAME-qN-tx */ struct xen_netif_tx_back_ring tx; struct sk_buff_head tx_queue; struct page *mmap_pages[MAX_PENDING_REQS]; @@ -150,7 +171,7 @@ struct xenvif { /* When feature-split-event-channels = 0, tx_irq = rx_irq. */ unsigned int rx_irq; /* Only used when feature-split-event-channels = 1 */ - char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */ + char rx_irq_name[IRQ_NAME_SIZE]; /* DEVNAME-qN-rx */ struct xen_netif_rx_back_ring rx; struct sk_buff_head rx_queue; RING_IDX rx_last_skb_slots; @@ -165,6 +186,22 @@ struct xenvif { */ struct xenvif_rx_meta meta[XEN_NETIF_RX_RING_SIZE]; + /* 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; + u64 credit_window_start; + + /* Statistics */ + struct xenvif_stats stats; +}; + +struct xenvif { + /* Unique identifier for this interface. */ + domid_t domid; + unsigned int handle; + u8 fe_dev_addr[6]; /* Frontend feature information. */ @@ -178,19 +215,13 @@ struct xenvif { /* Internal feature information. */ u8 can_queue:1; /* can queue packets for receiver? */ - /* 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; - u64 credit_window_start; + /* Is this interface disabled? True when backend discovers + * frontend is rogue. + */ + bool disabled; - /* Statistics */ - unsigned long rx_gso_checksum_fixup; - unsigned long tx_zerocopy_sent; - unsigned long tx_zerocopy_success; - unsigned long tx_zerocopy_fail; - unsigned long tx_frag_overflow; + /* Queues */ + struct xenvif_queue *queues; /* Miscellaneous private stuff. */ struct net_device *dev; @@ -205,7 +236,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, unsigned int handle); -int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, +int xenvif_init_queue(struct xenvif_queue *queue); + +int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int tx_evtchn, unsigned int rx_evtchn); void xenvif_disconnect(struct xenvif *vif); @@ -216,44 +249,47 @@ void xenvif_xenbus_fini(void); int xenvif_schedulable(struct xenvif *vif); -int xenvif_must_stop_queue(struct xenvif *vif); +int xenvif_must_stop_queue(struct xenvif_queue *queue); + +int xenvif_queue_stopped(struct xenvif_queue *queue); +void xenvif_wake_queue(struct xenvif_queue *queue); /* (Un)Map communication rings. */ -void xenvif_unmap_frontend_rings(struct xenvif *vif); -int xenvif_map_frontend_rings(struct xenvif *vif, +void xenvif_unmap_frontend_rings(struct xenvif_queue *queue); +int xenvif_map_frontend_rings(struct xenvif_queue *queue, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref); /* Check for SKBs from frontend and schedule backend processing */ -void xenvif_napi_schedule_or_enable_events(struct xenvif *vif); +void xenvif_napi_schedule_or_enable_events(struct xenvif_queue *queue); /* Prevent the device from generating any further traffic. */ void xenvif_carrier_off(struct xenvif *vif); -int xenvif_tx_action(struct xenvif *vif, int budget); +int xenvif_tx_action(struct xenvif_queue *queue, int budget); int xenvif_kthread_guest_rx(void *data); -void xenvif_kick_thread(struct xenvif *vif); +void xenvif_kick_thread(struct xenvif_queue *queue); int xenvif_dealloc_kthread(void *data); /* Determine whether the needed number of slots (req) are available, * and set req_event if not. */ -bool xenvif_rx_ring_slots_available(struct xenvif *vif, int needed); +bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue, int needed); -void xenvif_stop_queue(struct xenvif *vif); +void xenvif_carrier_on(struct xenvif *vif); /* Callback from stack when TX packet can be released */ void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success); /* Unmap a pending page and release it back to the guest */ -void xenvif_idx_unmap(struct xenvif *vif, u16 pending_idx); +void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); -static inline pending_ring_idx_t nr_pending_reqs(struct xenvif *vif) +static inline pending_ring_idx_t nr_pending_reqs(struct xenvif_queue *queue) { return MAX_PENDING_REQS - - vif->pending_prod + vif->pending_cons; + queue->pending_prod + queue->pending_cons; } /* Callback from stack when TX packet can be released */ |