aboutsummaryrefslogtreecommitdiffstats
path: root/xen-2.4.16
diff options
context:
space:
mode:
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-02-15 16:04:37 +0000
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>2003-02-15 16:04:37 +0000
commit646c9dc643a42520a4eda85902bbf8e17d60b958 (patch)
tree7be71ca929ccbaaffbdde83720042e88f0524514 /xen-2.4.16
parente2c3c2e000c3614809e4033fd65ea331296ad7e8 (diff)
downloadxen-646c9dc643a42520a4eda85902bbf8e17d60b958.tar.gz
xen-646c9dc643a42520a4eda85902bbf8e17d60b958.tar.bz2
xen-646c9dc643a42520a4eda85902bbf8e17d60b958.zip
bitkeeper revision 1.44 (3e4e65159dO6gZq2mxyfYFsgJFKbtw)
dev.c, vif.h, network.c: Fixed network transmit. Update consumer index *after* packet is transmitted :-)
Diffstat (limited to 'xen-2.4.16')
-rw-r--r--xen-2.4.16/common/network.c89
-rw-r--r--xen-2.4.16/include/xeno/vif.h9
-rw-r--r--xen-2.4.16/net/dev.c23
3 files changed, 57 insertions, 64 deletions
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) )