diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 3 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 31 | ||||
-rw-r--r-- | drivers/net/hyperv/rndis_filter.c | 15 |
3 files changed, 27 insertions, 22 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index b09c4fca1805..6b5f75217694 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -1427,9 +1427,6 @@ struct rndis_message { ((void *) rndis_msg) -#define __struct_bcount(x) - - #define RNDIS_HEADER_SIZE (sizeof(struct rndis_message) - \ sizeof(union rndis_message_container)) diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 0e71164849dd..989b7cd99380 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -1209,6 +1209,10 @@ static struct hv_device *netvsc_channel_to_device(struct vmbus_channel *channel) return primary ? primary->device_obj : channel->device_obj; } +/* Network processing softirq + * Process data in incoming ring buffer from host + * Stops when ring is empty or budget is met or exceeded. + */ int netvsc_poll(struct napi_struct *napi, int budget) { struct netvsc_channel *nvchan @@ -1238,7 +1242,11 @@ int netvsc_poll(struct napi_struct *napi, int budget) } hv_pkt_iter_close(channel); - /* If ring is empty and NAPI is not doing polling */ + /* If budget was not exhausted and + * not doing busy poll + * then re-enable host interrupts + * and reschedule if ring is not empty. + */ if (work_done < budget && napi_complete_done(napi, work_done) && hv_end_read(&channel->inbound) != 0) @@ -1248,23 +1256,17 @@ int netvsc_poll(struct napi_struct *napi, int budget) return work_done; } +/* Call back when data is available in host ring buffer. + * Processing is deferred until network softirq (NAPI) + */ void netvsc_channel_cb(void *context) { - struct vmbus_channel *channel = context; - struct hv_device *device = netvsc_channel_to_device(channel); - u16 q_idx = channel->offermsg.offer.sub_channel_index; - struct netvsc_device *net_device; - struct net_device *ndev; - - ndev = hv_get_drvdata(device); - if (unlikely(!ndev)) - return; + struct netvsc_channel *nvchan = context; /* disable interupts from host */ - hv_begin_read(&channel->inbound); + hv_begin_read(&nvchan->channel->inbound); - net_device = net_device_to_netvsc_device(ndev); - napi_schedule(&net_device->chan_table[q_idx].napi); + napi_schedule(&nvchan->napi); } /* @@ -1294,7 +1296,8 @@ int netvsc_device_add(struct hv_device *device, /* Open the channel */ ret = vmbus_open(device->channel, ring_size * PAGE_SIZE, ring_size * PAGE_SIZE, NULL, 0, - netvsc_channel_cb, device->channel); + netvsc_channel_cb, + net_device->chan_table); if (ret != 0) { netdev_err(ndev, "unable to open channel: %d\n", ret); diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index d7b6311e6c19..382b9a62e3c4 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -996,23 +996,28 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc) hv_get_drvdata(new_sc->primary_channel->device_obj); struct netvsc_device *nvscdev = net_device_to_netvsc_device(ndev); u16 chn_index = new_sc->offermsg.offer.sub_channel_index; - int ret; + struct netvsc_channel *nvchan; unsigned long flags; + int ret; if (chn_index >= nvscdev->num_chn) return; - nvscdev->chan_table[chn_index].mrc.buf + nvchan = nvscdev->chan_table + chn_index; + nvchan->mrc.buf = vzalloc(NETVSC_RECVSLOT_MAX * sizeof(struct recv_comp_data)); + if (!nvchan->mrc.buf) + return; + ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE, nvscdev->ring_size * PAGE_SIZE, NULL, 0, - netvsc_channel_cb, new_sc); + netvsc_channel_cb, nvchan); if (ret == 0) - nvscdev->chan_table[chn_index].channel = new_sc; + nvchan->channel = new_sc; - napi_enable(&nvscdev->chan_table[chn_index].napi); + napi_enable(&nvchan->napi); spin_lock_irqsave(&nvscdev->sc_lock, flags); nvscdev->num_sc_offered--; |