diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 82 |
1 files changed, 72 insertions, 10 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 5f736f1ceeae..72b0d26fd46d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1088,6 +1088,11 @@ int dev_open(struct net_device *dev) | |||
1088 | dev->flags |= IFF_UP; | 1088 | dev->flags |= IFF_UP; |
1089 | 1089 | ||
1090 | /* | 1090 | /* |
1091 | * Enable NET_DMA | ||
1092 | */ | ||
1093 | net_dmaengine_get(); | ||
1094 | |||
1095 | /* | ||
1091 | * Initialize multicasting status | 1096 | * Initialize multicasting status |
1092 | */ | 1097 | */ |
1093 | dev_set_rx_mode(dev); | 1098 | dev_set_rx_mode(dev); |
@@ -1164,6 +1169,11 @@ int dev_close(struct net_device *dev) | |||
1164 | */ | 1169 | */ |
1165 | call_netdevice_notifiers(NETDEV_DOWN, dev); | 1170 | call_netdevice_notifiers(NETDEV_DOWN, dev); |
1166 | 1171 | ||
1172 | /* | ||
1173 | * Shutdown NET_DMA | ||
1174 | */ | ||
1175 | net_dmaengine_put(); | ||
1176 | |||
1167 | return 0; | 1177 | return 0; |
1168 | } | 1178 | } |
1169 | 1179 | ||
@@ -1524,7 +1534,19 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) | |||
1524 | skb->mac_len = skb->network_header - skb->mac_header; | 1534 | skb->mac_len = skb->network_header - skb->mac_header; |
1525 | __skb_pull(skb, skb->mac_len); | 1535 | __skb_pull(skb, skb->mac_len); |
1526 | 1536 | ||
1527 | if (WARN_ON(skb->ip_summed != CHECKSUM_PARTIAL)) { | 1537 | if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { |
1538 | struct net_device *dev = skb->dev; | ||
1539 | struct ethtool_drvinfo info = {}; | ||
1540 | |||
1541 | if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) | ||
1542 | dev->ethtool_ops->get_drvinfo(dev, &info); | ||
1543 | |||
1544 | WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d " | ||
1545 | "ip_summed=%d", | ||
1546 | info.driver, dev ? dev->features : 0L, | ||
1547 | skb->sk ? skb->sk->sk_route_caps : 0L, | ||
1548 | skb->len, skb->data_len, skb->ip_summed); | ||
1549 | |||
1528 | if (skb_header_cloned(skb) && | 1550 | if (skb_header_cloned(skb) && |
1529 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 1551 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
1530 | return ERR_PTR(err); | 1552 | return ERR_PTR(err); |
@@ -2382,6 +2404,9 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2382 | if (!(skb->dev->features & NETIF_F_GRO)) | 2404 | if (!(skb->dev->features & NETIF_F_GRO)) |
2383 | goto normal; | 2405 | goto normal; |
2384 | 2406 | ||
2407 | if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list) | ||
2408 | goto normal; | ||
2409 | |||
2385 | rcu_read_lock(); | 2410 | rcu_read_lock(); |
2386 | list_for_each_entry_rcu(ptype, head, list) { | 2411 | list_for_each_entry_rcu(ptype, head, list) { |
2387 | struct sk_buff *p; | 2412 | struct sk_buff *p; |
@@ -2463,6 +2488,9 @@ static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2463 | 2488 | ||
2464 | int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 2489 | int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
2465 | { | 2490 | { |
2491 | if (netpoll_receive_skb(skb)) | ||
2492 | return NET_RX_DROP; | ||
2493 | |||
2466 | switch (__napi_gro_receive(napi, skb)) { | 2494 | switch (__napi_gro_receive(napi, skb)) { |
2467 | case -1: | 2495 | case -1: |
2468 | return netif_receive_skb(skb); | 2496 | return netif_receive_skb(skb); |
@@ -2478,12 +2506,6 @@ EXPORT_SYMBOL(napi_gro_receive); | |||
2478 | 2506 | ||
2479 | void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | 2507 | void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) |
2480 | { | 2508 | { |
2481 | skb_shinfo(skb)->nr_frags = 0; | ||
2482 | |||
2483 | skb->len -= skb->data_len; | ||
2484 | skb->truesize -= skb->data_len; | ||
2485 | skb->data_len = 0; | ||
2486 | |||
2487 | __skb_pull(skb, skb_headlen(skb)); | 2509 | __skb_pull(skb, skb_headlen(skb)); |
2488 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | 2510 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); |
2489 | 2511 | ||
@@ -2517,6 +2539,7 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi, | |||
2517 | 2539 | ||
2518 | if (!pskb_may_pull(skb, ETH_HLEN)) { | 2540 | if (!pskb_may_pull(skb, ETH_HLEN)) { |
2519 | napi_reuse_skb(napi, skb); | 2541 | napi_reuse_skb(napi, skb); |
2542 | skb = NULL; | ||
2520 | goto out; | 2543 | goto out; |
2521 | } | 2544 | } |
2522 | 2545 | ||
@@ -2538,6 +2561,9 @@ int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) | |||
2538 | if (!skb) | 2561 | if (!skb) |
2539 | goto out; | 2562 | goto out; |
2540 | 2563 | ||
2564 | if (netpoll_receive_skb(skb)) | ||
2565 | goto out; | ||
2566 | |||
2541 | err = NET_RX_SUCCESS; | 2567 | err = NET_RX_SUCCESS; |
2542 | 2568 | ||
2543 | switch (__napi_gro_receive(napi, skb)) { | 2569 | switch (__napi_gro_receive(napi, skb)) { |
@@ -4424,6 +4450,45 @@ err_uninit: | |||
4424 | } | 4450 | } |
4425 | 4451 | ||
4426 | /** | 4452 | /** |
4453 | * init_dummy_netdev - init a dummy network device for NAPI | ||
4454 | * @dev: device to init | ||
4455 | * | ||
4456 | * This takes a network device structure and initialize the minimum | ||
4457 | * amount of fields so it can be used to schedule NAPI polls without | ||
4458 | * registering a full blown interface. This is to be used by drivers | ||
4459 | * that need to tie several hardware interfaces to a single NAPI | ||
4460 | * poll scheduler due to HW limitations. | ||
4461 | */ | ||
4462 | int init_dummy_netdev(struct net_device *dev) | ||
4463 | { | ||
4464 | /* Clear everything. Note we don't initialize spinlocks | ||
4465 | * are they aren't supposed to be taken by any of the | ||
4466 | * NAPI code and this dummy netdev is supposed to be | ||
4467 | * only ever used for NAPI polls | ||
4468 | */ | ||
4469 | memset(dev, 0, sizeof(struct net_device)); | ||
4470 | |||
4471 | /* make sure we BUG if trying to hit standard | ||
4472 | * register/unregister code path | ||
4473 | */ | ||
4474 | dev->reg_state = NETREG_DUMMY; | ||
4475 | |||
4476 | /* initialize the ref count */ | ||
4477 | atomic_set(&dev->refcnt, 1); | ||
4478 | |||
4479 | /* NAPI wants this */ | ||
4480 | INIT_LIST_HEAD(&dev->napi_list); | ||
4481 | |||
4482 | /* a dummy interface is started by default */ | ||
4483 | set_bit(__LINK_STATE_PRESENT, &dev->state); | ||
4484 | set_bit(__LINK_STATE_START, &dev->state); | ||
4485 | |||
4486 | return 0; | ||
4487 | } | ||
4488 | EXPORT_SYMBOL_GPL(init_dummy_netdev); | ||
4489 | |||
4490 | |||
4491 | /** | ||
4427 | * register_netdev - register a network device | 4492 | * register_netdev - register a network device |
4428 | * @dev: device to register | 4493 | * @dev: device to register |
4429 | * | 4494 | * |
@@ -5151,9 +5216,6 @@ static int __init net_dev_init(void) | |||
5151 | hotcpu_notifier(dev_cpu_callback, 0); | 5216 | hotcpu_notifier(dev_cpu_callback, 0); |
5152 | dst_init(); | 5217 | dst_init(); |
5153 | dev_mcast_init(); | 5218 | dev_mcast_init(); |
5154 | #ifdef CONFIG_NET_DMA | ||
5155 | dmaengine_get(); | ||
5156 | #endif | ||
5157 | rc = 0; | 5219 | rc = 0; |
5158 | out: | 5220 | out: |
5159 | return rc; | 5221 | return rc; |