for_each_rx_queue_cnic(bp, i) {
                netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
                               bnx2x_poll, NAPI_POLL_WEIGHT);
-               napi_hash_add(&bnx2x_fp(bp, i, napi));
        }
 }
 
        for_each_eth_queue(bp, i) {
                netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
                               bnx2x_poll, NAPI_POLL_WEIGHT);
-               napi_hash_add(&bnx2x_fp(bp, i, napi));
        }
 }
 
 
                        bnapi = bp->bnapi[i];
                        netif_napi_add(bp->dev, &bnapi->napi,
                                       bnxt_poll, 64);
-                       napi_hash_add(&bnapi->napi);
                }
        } else {
                bnapi = bp->bnapi[0];
                netif_napi_add(bp->dev, &bnapi->napi, bnxt_poll, 64);
-               napi_hash_add(&bnapi->napi);
        }
 }
 
 
                goto err;
 
        netif_napi_add(dev, &iq->napi, napi_rx_handler, 64);
-       napi_hash_add(&iq->napi);
        iq->cur_desc = iq->desc;
        iq->cidx = 0;
        iq->gen = 1;
 
        switch (vnic_dev_get_intr_mode(enic->vdev)) {
        default:
                netif_napi_add(netdev, &enic->napi[0], enic_poll, 64);
-               napi_hash_add(&enic->napi[0]);
                break;
        case VNIC_DEV_INTR_MODE_MSIX:
                for (i = 0; i < enic->rq_count; i++) {
                        netif_napi_add(netdev, &enic->napi[i],
                                enic_poll_msix_rq, NAPI_POLL_WEIGHT);
-                       napi_hash_add(&enic->napi[i]);
                }
                for (i = 0; i < enic->wq_count; i++)
                        netif_napi_add(netdev, &enic->napi[enic_cq_wq(enic, i)],
 
                                eqo->affinity_mask);
                netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
                               BE_NAPI_WEIGHT);
-               napi_hash_add(&eqo->napi);
        }
        return 0;
 }
 
        /* initialize NAPI */
        netif_napi_add(adapter->netdev, &q_vector->napi,
                       ixgbe_poll, 64);
-       napi_hash_add(&q_vector->napi);
 
 #ifdef CONFIG_NET_RX_BUSY_POLL
        /* initialize busy poll */
 
                q_vector->v_idx = q_idx;
                netif_napi_add(adapter->netdev, &q_vector->napi,
                               ixgbevf_poll, 64);
-#ifdef CONFIG_NET_RX_BUSY_POLL
-               napi_hash_add(&q_vector->napi);
-#endif
                adapter->q_vector[q_idx] = q_vector;
        }
 
 
        cq->mcq.comp  = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
        cq->mcq.event = mlx4_en_cq_event;
 
-       if (cq->is_tx) {
+       if (cq->is_tx)
                netif_tx_napi_add(cq->dev, &cq->napi, mlx4_en_poll_tx_cq,
                                  NAPI_POLL_WEIGHT);
-       } else {
+       else
                netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
-               napi_hash_add(&cq->napi);
-       }
 
        napi_enable(&cq->napi);
 
 
        mlx5e_build_channeltc_to_txq_map(priv, ix);
 
        netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64);
-       napi_hash_add(&c->napi);
 
        err = mlx5e_open_tx_cqs(c, cparam);
        if (err)
 
                ss->dev = mgp->dev;
                netif_napi_add(ss->dev, &ss->napi, myri10ge_poll,
                               myri10ge_napi_weight);
-               napi_hash_add(&ss->napi);
        }
        return 0;
 abort:
 
        channel->napi_dev = efx->net_dev;
        netif_napi_add(channel->napi_dev, &channel->napi_str,
                       efx_poll, napi_weight);
-       napi_hash_add(&channel->napi_str);
        efx_channel_busy_poll_init(channel);
 }
 
 
                vi->rq[i].pages = NULL;
                netif_napi_add(vi->dev, &vi->rq[i].napi, virtnet_poll,
                               napi_weight);
-               napi_hash_add(&vi->rq[i].napi);
 
                sg_init_table(vi->rq[i].sg, ARRAY_SIZE(vi->rq[i].sg));
                ewma_pkt_len_init(&vi->rq[i].mrg_avg_pkt_len);
 
  *     @napi: napi context
  *
  * generate a new napi_id and store a @napi under it in napi_hash
+ * Used for busy polling (CONFIG_NET_RX_BUSY_POLL)
+ * Note: This is normally automatically done from netif_napi_add(),
+ * so might disappear in a future linux version.
  */
 void napi_hash_add(struct napi_struct *napi);
 
  * Warning: caller must observe rcu grace period
  * before freeing memory containing @napi, if
  * this function returns true.
+ * Note: core networking stack automatically calls it
+ * from netif_napi_del()
+ * Drivers might want to call this helper to combine all
+ * the needed rcu grace periods into a single one.
  */
 bool napi_hash_del(struct napi_struct *napi);
 
 
        napi->poll_owner = -1;
 #endif
        set_bit(NAPI_STATE_SCHED, &napi->state);
+       napi_hash_add(napi);
 }
 EXPORT_SYMBOL(netif_napi_add);
 
 }
 EXPORT_SYMBOL(napi_disable);
 
+/* Must be called in process context */
 void netif_napi_del(struct napi_struct *napi)
 {
+       might_sleep();
+       if (napi_hash_del(napi))
+               synchronize_net();
        list_del_init(&napi->dev_list);
        napi_free_frags(napi);
 
  *     This function does the last stage of destroying an allocated device
  *     interface. The reference to the device object is released.
  *     If this is the last reference then it will be freed.
+ *     Must be called in process context.
  */
 void free_netdev(struct net_device *dev)
 {
        struct napi_struct *p, *n;
 
+       might_sleep();
        netif_free_tx_queues(dev);
 #ifdef CONFIG_SYSFS
        kvfree(dev->_rx);