[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [1/2] [NET] back: Make extra info slot more generic
Hi: [NET] back: Make extra info slot more generic Based on suggestions by Keir Fraser, this patch makes the extra slot more generic by allowing it to be chained and giving each slot a type field. This makes it easier to add new extra slots such as checksum offset. I've also added GSO type constants specific for Xen. For now the conversion function between them and Linux is a noop. When and if they do diverge we can modify them accordingly. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff -r 9853b45712e8 -r b5ca6be8ad55 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Jun 28 13:55:13 2006 +1000 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Jun 29 10:16:22 2006 +1000 @@ -663,6 +663,35 @@ static void netbk_fill_frags(struct sk_b } } +int netbk_get_txtras(netif_t *netif, struct netif_tx_extra *txtras, + int work_to_do) +{ + struct netif_tx_extra *txtra; + int i = netif->tx.req_cons; + + do { + + if (unlikely(work_to_do-- <= 0)) { + DPRINTK("Missing extra info\n"); + return -EBADR; + } + + txtra = (struct netif_tx_extra *)RING_GET_REQUEST(&netif->tx, + i); + if (unlikely(!txtra->type || + txtra->type >= XEN_NETIF_TXTRA_TYPE_MAX)) { + netif->tx.req_cons = ++i; + DPRINTK("Invalid extra type: %d\n", txtra->type); + return -EINVAL; + } + + memcpy(txtras + txtra->type - 1, txtra, sizeof(*txtra)); + netif->tx.req_cons = ++i; + } while (txtra->flags & XEN_NETIF_TXTRA_MORE); + + return work_to_do; +} + /* Called after netfront has transmitted */ static void net_tx_action(unsigned long unused) { @@ -670,7 +699,7 @@ static void net_tx_action(unsigned long struct sk_buff *skb; netif_t *netif; netif_tx_request_t txreq; - struct netif_tx_extra txtra; + struct netif_tx_extra txtras[XEN_NETIF_TXTRA_TYPE_MAX - 1]; u16 pending_idx; RING_IDX i; gnttab_map_grant_ref_t *mop; @@ -732,16 +761,15 @@ static void net_tx_action(unsigned long work_to_do--; netif->tx.req_cons = ++i; + memset(txtras, 0, sizeof(txtras)); if (txreq.flags & NETTXF_extra_info) { - if (work_to_do-- <= 0) { - DPRINTK("Missing extra info\n"); - netbk_tx_err(netif, &txreq, i); + work_to_do = netbk_get_txtras(netif, txtras, + work_to_do); + if (unlikely(work_to_do < 0)) { + netbk_tx_err(netif, &txreq, 0); continue; } - - memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i), - sizeof(txtra)); - netif->tx.req_cons = ++i; + i = netif->tx.req_cons; } ret = netbk_count_requests(netif, &txreq, work_to_do); @@ -788,10 +816,15 @@ static void net_tx_action(unsigned long /* Packets passed to netif_rx() must have some headroom. */ skb_reserve(skb, 16); - if (txreq.flags & NETTXF_gso) { - skb_shinfo(skb)->gso_size = txtra.gso_size; - skb_shinfo(skb)->gso_segs = txtra.gso_segs; - skb_shinfo(skb)->gso_type = txtra.gso_type; + if (txtras[XEN_NETIF_TXTRA_TYPE_GSO - 1].type) { + struct netif_tx_extra *gso = txtras - 1 + + XEN_NETIF_TXTRA_TYPE_GSO; + + skb_shinfo(skb)->gso_size = gso->gso.size; + skb_shinfo(skb)->gso_segs = gso->gso.segs; + skb_shinfo(skb)->gso_type = + xen_gso_type_xen2linux(gso->gso.type); + } gnttab_set_map_op(mop, MMAP_VADDR(pending_idx), diff -r 9853b45712e8 -r b5ca6be8ad55 xen/include/public/io/netif.h --- a/xen/include/public/io/netif.h Wed Jun 28 13:55:13 2006 +1000 +++ b/xen/include/public/io/netif.h Thu Jun 29 10:16:22 2006 +1000 @@ -31,12 +31,28 @@ #define _NETTXF_more_data (2) #define NETTXF_more_data (1U<<_NETTXF_more_data) -/* Packet has GSO fields. */ -#define _NETTXF_gso (3) -#define NETTXF_gso (1U<<_NETTXF_gso) +/* Packet to be folloed by extra descritptor. */ +#define _NETTXF_extra_info (3) +#define NETTXF_extra_info (1U<<_NETTXF_extra_info) -/* Packet to be folloed by extra descritptor. */ -#define NETTXF_extra_info (NETTXF_gso) +enum { + XEN_NETIF_TXTRA_TYPE_GSO = 1, + XEN_NETIF_TXTRA_TYPE_MAX, +}; + +enum { + XEN_NETIF_TXTRA_MORE = 1 << 0, +}; + +enum { + /* TCP over IPv4. */ + XEN_GSO_TCPV4 = 1 << 0, + /* UDP over IPv4. */ + XEN_GSO_UDPV4 = 1 << 1, + + /* Packet header must be verified. */ + XEN_GSO_DODGY = 1 << 2, +}; struct netif_tx_request { grant_ref_t gref; /* Reference to buffer page */ @@ -47,11 +63,35 @@ struct netif_tx_request { }; typedef struct netif_tx_request netif_tx_request_t; -/* This structure needs to fit within netif_tx_request for compatibility. */ +/* + * This structure needs to fit within both netif_tx_request and + * netif_rx_response for compatibility. + */ struct netif_tx_extra { - uint16_t gso_size; /* GSO MSS. */ - uint16_t gso_segs; /* GSO segment count. */ - uint16_t gso_type; /* GSO type. */ + /* Type of extra info. */ + uint8_t type; + /* Flags for this info. */ + uint8_t flags; + + union { + /* + * Maximum payload size of each segment. For example, for TCP this is + * just the path MSS. + */ + uint16_t size; + + /* + * Number of GSO segments. This is the number of segments that have to + * be generated for this packet given the MSS. + */ + uint16_t segs; + + /* + * GSO type. This determines the protocol of the packet and any extra + * features required to segment the packet properly. + */ + uint16_t type; + } gso; }; struct netif_tx_response { @@ -94,6 +134,17 @@ DEFINE_RING_TYPES(netif_rx, struct netif #define NETIF_RSP_OKAY 0 #define NETIF_RSP_NULL 1 +/* For now the GSO types are identical. */ +static inline int xen_gso_type_linux2xen(int type) +{ + return type; +} + +static inline int xen_gso_type_xen2linux(int type) +{ + return type; +} + #endif /* _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |