|
@@ -16,7 +16,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
16
|
16
|
#define NETFRONT_NUM_TX_DESC 16
|
17
|
17
|
|
18
|
18
|
/** Number of receive ring entries */
|
19
|
|
-#define NETFRONT_NUM_RX_DESC 8
|
|
19
|
+#define NETFRONT_NUM_RX_DESC 32
|
|
20
|
+
|
|
21
|
+/** Receive ring fill level
|
|
22
|
+ *
|
|
23
|
+ * The xen-netback driver from kernels 3.18 to 4.2 inclusive have a
|
|
24
|
+ * bug (CA-163395) which prevents packet reception if fewer than 18
|
|
25
|
+ * receive descriptors are available. This was fixed in upstream
|
|
26
|
+ * kernel commit d5d4852 ("xen-netback: require fewer guest Rx slots
|
|
27
|
+ * when not using GSO").
|
|
28
|
+ *
|
|
29
|
+ * We provide 18 receive descriptors to avoid unpleasant silent
|
|
30
|
+ * failures on these kernel versions.
|
|
31
|
+ */
|
|
32
|
+#define NETFRONT_RX_FILL 18
|
20
|
33
|
|
21
|
34
|
/** Grant reference indices */
|
22
|
35
|
enum netfront_ref_index {
|
|
@@ -88,6 +101,21 @@ netfront_init_ring ( struct netfront_ring *ring, const char *ref_key,
|
88
|
101
|
ring->ids = ids;
|
89
|
102
|
}
|
90
|
103
|
|
|
104
|
+/**
|
|
105
|
+ * Calculate descriptor ring fill level
|
|
106
|
+ *
|
|
107
|
+ * @v ring Descriptor ring
|
|
108
|
+ * @v fill Fill level
|
|
109
|
+ */
|
|
110
|
+static inline __attribute__ (( always_inline )) unsigned int
|
|
111
|
+netfront_ring_fill ( struct netfront_ring *ring ) {
|
|
112
|
+ unsigned int fill_level;
|
|
113
|
+
|
|
114
|
+ fill_level = ( ring->id_prod - ring->id_cons );
|
|
115
|
+ assert ( fill_level <= ring->count );
|
|
116
|
+ return fill_level;
|
|
117
|
+}
|
|
118
|
+
|
91
|
119
|
/**
|
92
|
120
|
* Check whether or not descriptor ring is full
|
93
|
121
|
*
|
|
@@ -96,11 +124,8 @@ netfront_init_ring ( struct netfront_ring *ring, const char *ref_key,
|
96
|
124
|
*/
|
97
|
125
|
static inline __attribute__ (( always_inline )) int
|
98
|
126
|
netfront_ring_is_full ( struct netfront_ring *ring ) {
|
99
|
|
- unsigned int fill_level;
|
100
|
127
|
|
101
|
|
- fill_level = ( ring->id_prod - ring->id_cons );
|
102
|
|
- assert ( fill_level <= ring->count );
|
103
|
|
- return ( fill_level >= ring->count );
|
|
128
|
+ return ( netfront_ring_fill ( ring ) >= ring->count );
|
104
|
129
|
}
|
105
|
130
|
|
106
|
131
|
/**
|
|
@@ -112,7 +137,7 @@ netfront_ring_is_full ( struct netfront_ring *ring ) {
|
112
|
137
|
static inline __attribute__ (( always_inline )) int
|
113
|
138
|
netfront_ring_is_empty ( struct netfront_ring *ring ) {
|
114
|
139
|
|
115
|
|
- return ( ring->id_prod == ring->id_cons );
|
|
140
|
+ return ( netfront_ring_fill ( ring ) == 0 );
|
116
|
141
|
}
|
117
|
142
|
|
118
|
143
|
/** A netfront NIC */
|