diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 155 |
1 files changed, 87 insertions, 68 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 5413dbf3d4ac..e66de0c12fc1 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -24,6 +24,13 @@ | |||
24 | #include <linux/virtio_net.h> | 24 | #include <linux/virtio_net.h> |
25 | #include <linux/scatterlist.h> | 25 | #include <linux/scatterlist.h> |
26 | 26 | ||
27 | static int napi_weight = 128; | ||
28 | module_param(napi_weight, int, 0444); | ||
29 | |||
30 | static int csum = 1, gso = 1; | ||
31 | module_param(csum, bool, 0444); | ||
32 | module_param(gso, bool, 0444); | ||
33 | |||
27 | /* FIXME: MTU in config. */ | 34 | /* FIXME: MTU in config. */ |
28 | #define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) | 35 | #define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) |
29 | 36 | ||
@@ -52,13 +59,14 @@ static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb) | |||
52 | sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); | 59 | sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); |
53 | } | 60 | } |
54 | 61 | ||
55 | static bool skb_xmit_done(struct virtqueue *rvq) | 62 | static void skb_xmit_done(struct virtqueue *svq) |
56 | { | 63 | { |
57 | struct virtnet_info *vi = rvq->vdev->priv; | 64 | struct virtnet_info *vi = svq->vdev->priv; |
58 | 65 | ||
59 | /* In case we were waiting for output buffers. */ | 66 | /* Suppress further interrupts. */ |
67 | svq->vq_ops->disable_cb(svq); | ||
68 | /* We were waiting for more output buffers. */ | ||
60 | netif_wake_queue(vi->dev); | 69 | netif_wake_queue(vi->dev); |
61 | return true; | ||
62 | } | 70 | } |
63 | 71 | ||
64 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, | 72 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, |
@@ -83,28 +91,16 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
83 | 91 | ||
84 | if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { | 92 | if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { |
85 | pr_debug("Needs csum!\n"); | 93 | pr_debug("Needs csum!\n"); |
86 | skb->ip_summed = CHECKSUM_PARTIAL; | 94 | if (!skb_partial_csum_set(skb,hdr->csum_start,hdr->csum_offset)) |
87 | skb->csum_start = hdr->csum_start; | ||
88 | skb->csum_offset = hdr->csum_offset; | ||
89 | if (skb->csum_start > skb->len - 2 | ||
90 | || skb->csum_offset > skb->len - 2) { | ||
91 | if (net_ratelimit()) | ||
92 | printk(KERN_WARNING "%s: csum=%u/%u len=%u\n", | ||
93 | dev->name, skb->csum_start, | ||
94 | skb->csum_offset, skb->len); | ||
95 | goto frame_err; | 95 | goto frame_err; |
96 | } | ||
97 | } | 96 | } |
98 | 97 | ||
99 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { | 98 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
100 | pr_debug("GSO!\n"); | 99 | pr_debug("GSO!\n"); |
101 | switch (hdr->gso_type) { | 100 | switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { |
102 | case VIRTIO_NET_HDR_GSO_TCPV4: | 101 | case VIRTIO_NET_HDR_GSO_TCPV4: |
103 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | 102 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; |
104 | break; | 103 | break; |
105 | case VIRTIO_NET_HDR_GSO_TCPV4_ECN: | ||
106 | skb_shinfo(skb)->gso_type = SKB_GSO_TCP_ECN; | ||
107 | break; | ||
108 | case VIRTIO_NET_HDR_GSO_UDP: | 104 | case VIRTIO_NET_HDR_GSO_UDP: |
109 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; | 105 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
110 | break; | 106 | break; |
@@ -118,6 +114,9 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
118 | goto frame_err; | 114 | goto frame_err; |
119 | } | 115 | } |
120 | 116 | ||
117 | if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN) | ||
118 | skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; | ||
119 | |||
121 | skb_shinfo(skb)->gso_size = hdr->gso_size; | 120 | skb_shinfo(skb)->gso_size = hdr->gso_size; |
122 | if (skb_shinfo(skb)->gso_size == 0) { | 121 | if (skb_shinfo(skb)->gso_size == 0) { |
123 | if (net_ratelimit()) | 122 | if (net_ratelimit()) |
@@ -170,12 +169,14 @@ static void try_fill_recv(struct virtnet_info *vi) | |||
170 | vi->rvq->vq_ops->kick(vi->rvq); | 169 | vi->rvq->vq_ops->kick(vi->rvq); |
171 | } | 170 | } |
172 | 171 | ||
173 | static bool skb_recv_done(struct virtqueue *rvq) | 172 | static void skb_recv_done(struct virtqueue *rvq) |
174 | { | 173 | { |
175 | struct virtnet_info *vi = rvq->vdev->priv; | 174 | struct virtnet_info *vi = rvq->vdev->priv; |
176 | netif_rx_schedule(vi->dev, &vi->napi); | 175 | /* Schedule NAPI, Suppress further interrupts if successful. */ |
177 | /* Suppress further interrupts. */ | 176 | if (netif_rx_schedule_prep(vi->dev, &vi->napi)) { |
178 | return false; | 177 | rvq->vq_ops->disable_cb(rvq); |
178 | __netif_rx_schedule(vi->dev, &vi->napi); | ||
179 | } | ||
179 | } | 180 | } |
180 | 181 | ||
181 | static int virtnet_poll(struct napi_struct *napi, int budget) | 182 | static int virtnet_poll(struct napi_struct *napi, int budget) |
@@ -201,7 +202,7 @@ again: | |||
201 | /* Out of packets? */ | 202 | /* Out of packets? */ |
202 | if (received < budget) { | 203 | if (received < budget) { |
203 | netif_rx_complete(vi->dev, napi); | 204 | netif_rx_complete(vi->dev, napi); |
204 | if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq)) | 205 | if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) |
205 | && netif_rx_reschedule(vi->dev, napi)) | 206 | && netif_rx_reschedule(vi->dev, napi)) |
206 | goto again; | 207 | goto again; |
207 | } | 208 | } |
@@ -236,8 +237,6 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
236 | 237 | ||
237 | pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest)); | 238 | pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest)); |
238 | 239 | ||
239 | free_old_xmit_skbs(vi); | ||
240 | |||
241 | /* Encode metadata header at front. */ | 240 | /* Encode metadata header at front. */ |
242 | hdr = skb_vnet_hdr(skb); | 241 | hdr = skb_vnet_hdr(skb); |
243 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 242 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
@@ -250,10 +249,9 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
250 | } | 249 | } |
251 | 250 | ||
252 | if (skb_is_gso(skb)) { | 251 | if (skb_is_gso(skb)) { |
252 | hdr->hdr_len = skb_transport_header(skb) - skb->data; | ||
253 | hdr->gso_size = skb_shinfo(skb)->gso_size; | 253 | hdr->gso_size = skb_shinfo(skb)->gso_size; |
254 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) | 254 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) |
255 | hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN; | ||
256 | else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) | ||
257 | hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; | 255 | hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; |
258 | else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) | 256 | else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) |
259 | hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; | 257 | hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; |
@@ -261,19 +259,34 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
261 | hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; | 259 | hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; |
262 | else | 260 | else |
263 | BUG(); | 261 | BUG(); |
262 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) | ||
263 | hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN; | ||
264 | } else { | 264 | } else { |
265 | hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE; | 265 | hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE; |
266 | hdr->gso_size = 0; | 266 | hdr->gso_size = hdr->hdr_len = 0; |
267 | } | 267 | } |
268 | 268 | ||
269 | vnet_hdr_to_sg(sg, skb); | 269 | vnet_hdr_to_sg(sg, skb); |
270 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; | 270 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; |
271 | __skb_queue_head(&vi->send, skb); | 271 | __skb_queue_head(&vi->send, skb); |
272 | |||
273 | again: | ||
274 | /* Free up any pending old buffers before queueing new ones. */ | ||
275 | free_old_xmit_skbs(vi); | ||
272 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | 276 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); |
273 | if (err) { | 277 | if (err) { |
274 | pr_debug("%s: virtio not prepared to send\n", dev->name); | 278 | pr_debug("%s: virtio not prepared to send\n", dev->name); |
275 | skb_unlink(skb, &vi->send); | ||
276 | netif_stop_queue(dev); | 279 | netif_stop_queue(dev); |
280 | |||
281 | /* Activate callback for using skbs: if this fails it | ||
282 | * means some were used in the meantime. */ | ||
283 | if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { | ||
284 | printk("Unlikely: restart svq failed\n"); | ||
285 | netif_start_queue(dev); | ||
286 | goto again; | ||
287 | } | ||
288 | __skb_unlink(skb, &vi->send); | ||
289 | |||
277 | return NETDEV_TX_BUSY; | 290 | return NETDEV_TX_BUSY; |
278 | } | 291 | } |
279 | vi->svq->vq_ops->kick(vi->svq); | 292 | vi->svq->vq_ops->kick(vi->svq); |
@@ -285,45 +298,31 @@ static int virtnet_open(struct net_device *dev) | |||
285 | { | 298 | { |
286 | struct virtnet_info *vi = netdev_priv(dev); | 299 | struct virtnet_info *vi = netdev_priv(dev); |
287 | 300 | ||
288 | try_fill_recv(vi); | 301 | napi_enable(&vi->napi); |
289 | 302 | ||
290 | /* If we didn't even get one input buffer, we're useless. */ | 303 | /* If all buffers were filled by other side before we napi_enabled, we |
291 | if (vi->num == 0) | 304 | * won't get another interrupt, so process any outstanding packets |
292 | return -ENOMEM; | 305 | * now. virtnet_poll wants re-enable the queue, so we disable here. */ |
306 | vi->rvq->vq_ops->disable_cb(vi->rvq); | ||
307 | netif_rx_schedule(vi->dev, &vi->napi); | ||
293 | 308 | ||
294 | napi_enable(&vi->napi); | ||
295 | return 0; | 309 | return 0; |
296 | } | 310 | } |
297 | 311 | ||
298 | static int virtnet_close(struct net_device *dev) | 312 | static int virtnet_close(struct net_device *dev) |
299 | { | 313 | { |
300 | struct virtnet_info *vi = netdev_priv(dev); | 314 | struct virtnet_info *vi = netdev_priv(dev); |
301 | struct sk_buff *skb; | ||
302 | 315 | ||
303 | napi_disable(&vi->napi); | 316 | napi_disable(&vi->napi); |
304 | 317 | ||
305 | /* networking core has neutered skb_xmit_done/skb_recv_done, so don't | ||
306 | * worry about races vs. get(). */ | ||
307 | vi->rvq->vq_ops->shutdown(vi->rvq); | ||
308 | while ((skb = __skb_dequeue(&vi->recv)) != NULL) { | ||
309 | kfree_skb(skb); | ||
310 | vi->num--; | ||
311 | } | ||
312 | vi->svq->vq_ops->shutdown(vi->svq); | ||
313 | while ((skb = __skb_dequeue(&vi->send)) != NULL) | ||
314 | kfree_skb(skb); | ||
315 | |||
316 | BUG_ON(vi->num != 0); | ||
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
319 | 320 | ||
320 | static int virtnet_probe(struct virtio_device *vdev) | 321 | static int virtnet_probe(struct virtio_device *vdev) |
321 | { | 322 | { |
322 | int err; | 323 | int err; |
323 | unsigned int len; | ||
324 | struct net_device *dev; | 324 | struct net_device *dev; |
325 | struct virtnet_info *vi; | 325 | struct virtnet_info *vi; |
326 | void *token; | ||
327 | 326 | ||
328 | /* Allocate ourselves a network device with room for our info */ | 327 | /* Allocate ourselves a network device with room for our info */ |
329 | dev = alloc_etherdev(sizeof(struct virtnet_info)); | 328 | dev = alloc_etherdev(sizeof(struct virtnet_info)); |
@@ -331,7 +330,6 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
331 | return -ENOMEM; | 330 | return -ENOMEM; |
332 | 331 | ||
333 | /* Set up network device as normal. */ | 332 | /* Set up network device as normal. */ |
334 | ether_setup(dev); | ||
335 | dev->open = virtnet_open; | 333 | dev->open = virtnet_open; |
336 | dev->stop = virtnet_close; | 334 | dev->stop = virtnet_close; |
337 | dev->hard_start_xmit = start_xmit; | 335 | dev->hard_start_xmit = start_xmit; |
@@ -339,42 +337,37 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
339 | SET_NETDEV_DEV(dev, &vdev->dev); | 337 | SET_NETDEV_DEV(dev, &vdev->dev); |
340 | 338 | ||
341 | /* Do we support "hardware" checksums? */ | 339 | /* Do we support "hardware" checksums? */ |
342 | token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_F, &len); | 340 | if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { |
343 | if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_NO_CSUM)) { | ||
344 | /* This opens up the world of extra features. */ | 341 | /* This opens up the world of extra features. */ |
345 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; | 342 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; |
346 | if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4)) | 343 | if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { |
347 | dev->features |= NETIF_F_TSO; | 344 | dev->features |= NETIF_F_TSO | NETIF_F_UFO |
348 | if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_UFO)) | 345 | | NETIF_F_TSO_ECN | NETIF_F_TSO6; |
349 | dev->features |= NETIF_F_UFO; | 346 | } |
350 | if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4_ECN)) | ||
351 | dev->features |= NETIF_F_TSO_ECN; | ||
352 | if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO6)) | ||
353 | dev->features |= NETIF_F_TSO6; | ||
354 | } | 347 | } |
355 | 348 | ||
356 | /* Configuration may specify what MAC to use. Otherwise random. */ | 349 | /* Configuration may specify what MAC to use. Otherwise random. */ |
357 | token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_MAC_F, &len); | 350 | if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { |
358 | if (token) { | 351 | vdev->config->get(vdev, |
359 | dev->addr_len = len; | 352 | offsetof(struct virtio_net_config, mac), |
360 | vdev->config->get(vdev, token, dev->dev_addr, len); | 353 | dev->dev_addr, dev->addr_len); |
361 | } else | 354 | } else |
362 | random_ether_addr(dev->dev_addr); | 355 | random_ether_addr(dev->dev_addr); |
363 | 356 | ||
364 | /* Set up our device-specific information */ | 357 | /* Set up our device-specific information */ |
365 | vi = netdev_priv(dev); | 358 | vi = netdev_priv(dev); |
366 | netif_napi_add(dev, &vi->napi, virtnet_poll, 16); | 359 | netif_napi_add(dev, &vi->napi, virtnet_poll, napi_weight); |
367 | vi->dev = dev; | 360 | vi->dev = dev; |
368 | vi->vdev = vdev; | 361 | vi->vdev = vdev; |
369 | 362 | ||
370 | /* We expect two virtqueues, receive then send. */ | 363 | /* We expect two virtqueues, receive then send. */ |
371 | vi->rvq = vdev->config->find_vq(vdev, skb_recv_done); | 364 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); |
372 | if (IS_ERR(vi->rvq)) { | 365 | if (IS_ERR(vi->rvq)) { |
373 | err = PTR_ERR(vi->rvq); | 366 | err = PTR_ERR(vi->rvq); |
374 | goto free; | 367 | goto free; |
375 | } | 368 | } |
376 | 369 | ||
377 | vi->svq = vdev->config->find_vq(vdev, skb_xmit_done); | 370 | vi->svq = vdev->config->find_vq(vdev, 1, skb_xmit_done); |
378 | if (IS_ERR(vi->svq)) { | 371 | if (IS_ERR(vi->svq)) { |
379 | err = PTR_ERR(vi->svq); | 372 | err = PTR_ERR(vi->svq); |
380 | goto free_recv; | 373 | goto free_recv; |
@@ -389,10 +382,22 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
389 | pr_debug("virtio_net: registering device failed\n"); | 382 | pr_debug("virtio_net: registering device failed\n"); |
390 | goto free_send; | 383 | goto free_send; |
391 | } | 384 | } |
385 | |||
386 | /* Last of all, set up some receive buffers. */ | ||
387 | try_fill_recv(vi); | ||
388 | |||
389 | /* If we didn't even get one input buffer, we're useless. */ | ||
390 | if (vi->num == 0) { | ||
391 | err = -ENOMEM; | ||
392 | goto unregister; | ||
393 | } | ||
394 | |||
392 | pr_debug("virtnet: registered device %s\n", dev->name); | 395 | pr_debug("virtnet: registered device %s\n", dev->name); |
393 | vdev->priv = vi; | 396 | vdev->priv = vi; |
394 | return 0; | 397 | return 0; |
395 | 398 | ||
399 | unregister: | ||
400 | unregister_netdev(dev); | ||
396 | free_send: | 401 | free_send: |
397 | vdev->config->del_vq(vi->svq); | 402 | vdev->config->del_vq(vi->svq); |
398 | free_recv: | 403 | free_recv: |
@@ -405,6 +410,20 @@ free: | |||
405 | static void virtnet_remove(struct virtio_device *vdev) | 410 | static void virtnet_remove(struct virtio_device *vdev) |
406 | { | 411 | { |
407 | struct virtnet_info *vi = vdev->priv; | 412 | struct virtnet_info *vi = vdev->priv; |
413 | struct sk_buff *skb; | ||
414 | |||
415 | /* Stop all the virtqueues. */ | ||
416 | vdev->config->reset(vdev); | ||
417 | |||
418 | /* Free our skbs in send and recv queues, if any. */ | ||
419 | while ((skb = __skb_dequeue(&vi->recv)) != NULL) { | ||
420 | kfree_skb(skb); | ||
421 | vi->num--; | ||
422 | } | ||
423 | while ((skb = __skb_dequeue(&vi->send)) != NULL) | ||
424 | kfree_skb(skb); | ||
425 | |||
426 | BUG_ON(vi->num != 0); | ||
408 | 427 | ||
409 | vdev->config->del_vq(vi->svq); | 428 | vdev->config->del_vq(vi->svq); |
410 | vdev->config->del_vq(vi->rvq); | 429 | vdev->config->del_vq(vi->rvq); |