From 646c9dc643a42520a4eda85902bbf8e17d60b958 Mon Sep 17 00:00:00 2001 From: "kaf24@labyrinth.cl.cam.ac.uk" Date: Sat, 15 Feb 2003 16:04:37 +0000 Subject: bitkeeper revision 1.44 (3e4e65159dO6gZq2mxyfYFsgJFKbtw) dev.c, vif.h, network.c: Fixed network transmit. Update consumer index *after* packet is transmitted :-) --- xen-2.4.16/common/network.c | 89 +++++++++++++++++++------------------------ xen-2.4.16/include/xeno/vif.h | 9 +---- xen-2.4.16/net/dev.c | 23 +++++++---- 3 files changed, 57 insertions(+), 64 deletions(-) (limited to 'xen-2.4.16') diff --git a/xen-2.4.16/common/network.c b/xen-2.4.16/common/network.c index 80fad27cc7..687d3e2403 100644 --- a/xen-2.4.16/common/network.c +++ b/xen-2.4.16/common/network.c @@ -65,22 +65,18 @@ net_vif_t *create_net_vif(int domain) new_ring = dom_task->net_ring_base + dom_task->num_net_vifs; memset(new_ring, 0, sizeof(net_ring_t)); - // allocate the shadow ring. - // maybe these should be kmem_cache instead of kmalloc? - shadow_ring = kmalloc(sizeof(net_shadow_ring_t), GFP_KERNEL); if (shadow_ring == NULL) goto fail; - shadow_ring->tx_ring = kmalloc(TX_RING_SIZE - * sizeof(tx_shadow_entry_t), GFP_KERNEL); shadow_ring->rx_ring = kmalloc(RX_RING_SIZE * sizeof(rx_shadow_entry_t), GFP_KERNEL); - if ((shadow_ring->tx_ring == NULL) || (shadow_ring->rx_ring == NULL)) + if ( shadow_ring->rx_ring == NULL ) goto fail; shadow_ring->rx_prod = shadow_ring->rx_cons = shadow_ring->rx_idx = 0; + shadow_ring->tx_cons = 0; - // fill in the new vif struct. + /* Fill in the new vif struct. */ new_vif->net_ring = new_ring; new_vif->shadow_ring = shadow_ring; @@ -127,7 +123,6 @@ void destroy_net_vif(struct task_struct *p) sys_vif_list[p->net_vif_list[i]->id] = NULL; // system vif list not gc'ed write_unlock(&sys_vif_lock); - kfree(p->net_vif_list[i]->shadow_ring->tx_ring); kfree(p->net_vif_list[i]->shadow_ring->rx_ring); kfree(p->net_vif_list[i]->shadow_ring); kmem_cache_free(net_vif_cache, p->net_vif_list[i]); @@ -297,21 +292,23 @@ int net_find_rule(u8 nproto, u8 tproto, u32 src_addr, u32 dst_addr, u16 src_port while (ent) { - if ( ( (ent->r.src_interface == src_vif) - || (ent->r.src_interface == VIF_ANY_INTERFACE) ) - - && (!((ent->r.src_addr ^ src_addr) & ent->r.src_addr_mask )) - && (!((ent->r.dst_addr ^ dst_addr) & ent->r.dst_addr_mask )) - && (!((ent->r.src_port ^ src_port) & ent->r.src_port_mask )) - && (!((ent->r.dst_port ^ dst_port) & ent->r.dst_port_mask )) - - && ( - (ent->r.proto == NETWORK_PROTO_ANY) - || ((ent->r.proto == NETWORK_PROTO_IP) && (nproto == (u8)ETH_P_IP)) - || ((ent->r.proto == NETWORK_PROTO_ARP) && (nproto == (u8)ETH_P_ARP)) - || ((ent->r.proto == NETWORK_PROTO_TCP) && (tproto == IPPROTO_TCP)) - || ((ent->r.proto == NETWORK_PROTO_UDP) && (tproto == IPPROTO_UDP)) - ) + if ( ((ent->r.src_interface == src_vif) + || (ent->r.src_interface == VIF_ANY_INTERFACE)) && + + (!((ent->r.src_addr ^ src_addr) & ent->r.src_addr_mask )) && + (!((ent->r.dst_addr ^ dst_addr) & ent->r.dst_addr_mask )) && + (!((ent->r.src_port ^ src_port) & ent->r.src_port_mask )) && + (!((ent->r.dst_port ^ dst_port) & ent->r.dst_port_mask )) && + + ((ent->r.proto == NETWORK_PROTO_ANY) || + ((ent->r.proto == NETWORK_PROTO_IP) && + (nproto == (u8)ETH_P_IP)) || + ((ent->r.proto == NETWORK_PROTO_ARP) && + (nproto == (u8)ETH_P_ARP)) || + ((ent->r.proto == NETWORK_PROTO_TCP) && + (tproto == IPPROTO_TCP)) || + ((ent->r.proto == NETWORK_PROTO_UDP) && + (tproto == IPPROTO_UDP))) ) { break; @@ -358,40 +355,34 @@ int __net_get_target_vif(u8 *data, unsigned int len, int src_vif) case ETH_P_ARP: if ( len < 28 ) goto drop; target = net_find_rule((u8)ETH_P_ARP, 0, ntohl(*(u32 *)(nh_raw + 14)), - ntohl(*(u32 *)(nh_raw + 24)), 0, 0, - src_vif); + ntohl(*(u32 *)(nh_raw + 24)), 0, 0, + src_vif); break; case ETH_P_IP: if ( len < 20 ) goto drop; h_raw = data + ((*(unsigned char *)(nh_raw)) & 0x0f) * 4; - switch ( *(unsigned char *)(nh_raw + 9) ) - { - case IPPROTO_UDP: - case IPPROTO_TCP: - target = net_find_rule((u8)ETH_P_IP, *(u8 *)(nh_raw + 9), - ntohl(*(u32 *)(nh_raw + 12)), - ntohl(*(u32 *)(nh_raw + 16)), - ntohs(*(u16 *)(h_raw)), - ntohs(*(u16 *)(h_raw + 2)), - src_vif); - break; - - default: // ip-based protocol where we don't have ports. - target = net_find_rule((u8)ETH_P_IP, *(u8 *)(data + 9), - ntohl(*(u32 *)(nh_raw + 12)), - ntohl(*(u32 *)(nh_raw + 16)), - 0, - 0, - src_vif); - } - break; - + + /* XXX For now, we ignore ports. */ +#if 0 + target = net_find_rule((u8)ETH_P_IP, *(u8 *)(nh_raw + 9), + ntohl(*(u32 *)(nh_raw + 12)), + ntohl(*(u32 *)(nh_raw + 16)), + ntohs(*(u16 *)(h_raw)), + ntohs(*(u16 *)(h_raw + 2)), + src_vif); +#else + target = net_find_rule((u8)ETH_P_IP, *(u8 *)(data + 9), + ntohl(*(u32 *)(nh_raw + 12)), + ntohl(*(u32 *)(nh_raw + 16)), + 0, + 0, + src_vif); +#endif } return target; - drop: -//printk("Drop case!\n"); + drop: return VIF_DROP; } diff --git a/xen-2.4.16/include/xeno/vif.h b/xen-2.4.16/include/xeno/vif.h index 7d2878dabf..4af4f24435 100644 --- a/xen-2.4.16/include/xeno/vif.h +++ b/xen-2.4.16/include/xeno/vif.h @@ -25,13 +25,6 @@ * TX_RING_SIZE and RX_RING_SIZE are defined in the shared network.h. */ -typedef struct tx_shadow_entry_st { - unsigned long addr; - unsigned long size; - int status; - unsigned long flush_count; -} tx_shadow_entry_t; - typedef struct rx_shadow_entry_st { unsigned long addr; unsigned long size; @@ -40,9 +33,9 @@ typedef struct rx_shadow_entry_st { } rx_shadow_entry_t; typedef struct net_shadow_ring_st { - tx_shadow_entry_t *tx_ring; rx_shadow_entry_t *rx_ring; unsigned int rx_prod, rx_cons, rx_idx; + unsigned int tx_cons; /* ahead of shared tx_cons */ } net_shadow_ring_t; typedef struct net_vif_st { diff --git a/xen-2.4.16/net/dev.c b/xen-2.4.16/net/dev.c index 4e36aa0d60..1ce6e9649e 100644 --- a/xen-2.4.16/net/dev.c +++ b/xen-2.4.16/net/dev.c @@ -2003,6 +2003,7 @@ inline int init_tx_header(u8 *data, unsigned int len, struct net_device *dev) return 0; } + /* * tx_skb_release * @@ -2017,11 +2018,21 @@ void tx_skb_release(struct sk_buff *skb) { int i; - for (i= 0; i < skb_shinfo(skb)->nr_frags; i++) + for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) skb_shinfo(skb)->frags[i].page->tot_count--; skb_shinfo(skb)->nr_frags = 0; + + /* + * XXX This assumes that, per vif, SKBs are processed in-order! + * Also, like lots of code in here -- we assume direct access to the + * consumer and producer indexes. This is likely safe for the + * forseeable future. + */ + sys_vif_list[skb->src_vif]->net_ring->tx_cons = + TX_RING_INC(sys_vif_list[skb->src_vif]->net_ring->tx_cons); } + /* * do_net_update: @@ -2045,8 +2056,7 @@ long do_net_update(void) rx_shadow_entry_t *rx; unsigned long pfn; struct pfn_info *page; - unsigned long *g_pte; - + unsigned long *g_pte; for ( j = 0; j < current->num_net_vifs; j++) { @@ -2056,12 +2066,13 @@ long do_net_update(void) current_vif = current->net_vif_list[j]; net_ring = current_vif->net_ring; + shadow_ring = current_vif->shadow_ring; /* * PHASE 1 -- TRANSMIT RING */ - for ( i = net_ring->tx_cons; + for ( i = shadow_ring->tx_cons; i != net_ring->tx_prod; i = TX_RING_INC(i) ) { @@ -2176,14 +2187,12 @@ long do_net_update(void) unmap_domain_mem(g_data); } } - net_ring->tx_cons = i; + shadow_ring->tx_cons = i; /* * PHASE 2 -- RECEIVE RING */ - shadow_ring = current_vif->shadow_ring; - for ( i = shadow_ring->rx_prod; i != net_ring->rx_prod; i = RX_RING_INC(i) ) -- cgit v1.2.3