summaryrefslogtreecommitdiff
blob: 1e581586ab228c042b0ce744d42cfc106f012b10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# HG changeset 137 patch
# User Ian Campbell <ian.campbell@xensource.com>
# Date 1184590655 -3600
# Node ID 41918416db51d1eeaba7c71259e1c0f0ea3426f6
# Parent  34ebf92ad28d53f70ca02966c9f926f7d83bafbb
Subject: [NETFRONT] Implement netif_release_rx_bufs for the copying case.

Also reduce the log level when we are unable end foreign access to a
grant.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>

Acked-by: jbeulich@novell.com

Index: head-2007-08-07/drivers/xen/core/gnttab.c
===================================================================
--- head-2007-08-07.orig/drivers/xen/core/gnttab.c	2007-08-07 09:47:30.000000000 +0200
+++ head-2007-08-07/drivers/xen/core/gnttab.c	2007-08-07 09:58:05.000000000 +0200
@@ -186,7 +186,7 @@ int gnttab_end_foreign_access_ref(grant_
 	nflags = shared[ref].flags;
 	do {
 		if ((flags = nflags) & (GTF_reading|GTF_writing)) {
-			printk(KERN_ALERT "WARNING: g.e. still in use!\n");
+			printk(KERN_DEBUG "WARNING: g.e. still in use!\n");
 			return 0;
 		}
 	} while ((nflags = synch_cmpxchg_subword(&shared[ref].flags, flags, 0)) !=
@@ -206,7 +206,7 @@ void gnttab_end_foreign_access(grant_ref
 	} else {
 		/* XXX This needs to be fixed so that the ref and page are
 		   placed on a list to be freed up later. */
-		printk(KERN_WARNING
+		printk(KERN_DEBUG
 		       "WARNING: leaking g.e. and page still in use!\n");
 	}
 }
Index: head-2007-08-07/drivers/xen/netfront/netfront.c
===================================================================
--- head-2007-08-07.orig/drivers/xen/netfront/netfront.c	2007-08-07 09:47:09.000000000 +0200
+++ head-2007-08-07/drivers/xen/netfront/netfront.c	2007-08-07 09:58:05.000000000 +0200
@@ -1510,7 +1510,7 @@ static void netif_release_tx_bufs(struct
 	}
 }
 
-static void netif_release_rx_bufs(struct netfront_info *np)
+static void netif_release_rx_bufs_flip(struct netfront_info *np)
 {
 	struct mmu_update      *mmu = np->rx_mmu;
 	struct multicall_entry *mcl = np->rx_mcl;
@@ -1520,11 +1520,6 @@ static void netif_release_rx_bufs(struct
 	int xfer = 0, noxfer = 0, unused = 0;
 	int id, ref, rc;
 
-	if (np->copying_receiver) {
-		WPRINTK("%s: fix me for copying receiver.\n", __FUNCTION__);
-		return;
-	}
-
 	skb_queue_head_init(&free_list);
 
 	spin_lock_bh(&np->rx_lock);
@@ -1571,7 +1566,7 @@ static void netif_release_rx_bufs(struct
 		xfer++;
 	}
 
-	IPRINTK("%s: %d xfer, %d noxfer, %d unused\n",
+	DPRINTK("%s: %d xfer, %d noxfer, %d unused\n",
 		__FUNCTION__, xfer, noxfer, unused);
 
 	if (xfer) {
@@ -1598,6 +1593,45 @@ static void netif_release_rx_bufs(struct
 	spin_unlock_bh(&np->rx_lock);
 }
 
+static void netif_release_rx_bufs_copy(struct netfront_info *np)
+{
+	struct sk_buff *skb;
+	int i, ref;
+	int busy = 0, inuse = 0;
+
+	spin_lock_bh(&np->rx_lock);
+
+	for (i = 0; i < NET_RX_RING_SIZE; i++) {
+		ref = np->grant_rx_ref[i];
+
+		if (ref == GRANT_INVALID_REF)
+			continue;
+
+		inuse++;
+
+		skb = np->rx_skbs[i];
+
+		if (!gnttab_end_foreign_access_ref(ref, 0))
+		{
+			busy++;
+			continue;
+		}
+
+		gnttab_release_grant_reference(&np->gref_rx_head, ref);
+		np->grant_rx_ref[i] = GRANT_INVALID_REF;
+		add_id_to_freelist(np->rx_skbs, i);
+
+		skb_shinfo(skb)->nr_frags = 0;
+		dev_kfree_skb(skb);
+	}
+
+	if (busy)
+		DPRINTK("%s: Unable to release %d of %d inuse grant references out of %ld total.\n",
+			__FUNCTION__, busy, inuse, NET_RX_RING_SIZE);
+
+	spin_unlock_bh(&np->rx_lock);
+}
+
 static int network_close(struct net_device *dev)
 {
 	struct netfront_info *np = netdev_priv(dev);
@@ -1778,7 +1812,10 @@ static void netif_uninit(struct net_devi
 {
 	struct netfront_info *np = netdev_priv(dev);
 	netif_release_tx_bufs(np);
-	netif_release_rx_bufs(np);
+	if (np->copying_receiver)
+		netif_release_rx_bufs_copy(np);
+	else
+		netif_release_rx_bufs_flip(np);
 	gnttab_free_grant_references(np->gref_tx_head);
 	gnttab_free_grant_references(np->gref_rx_head);
 }