Now that receive area is parameterized, also need to adjust the
size of the ring for receive completions based on receive area.

Signed-off-by: Stephen Hemminger <sthem...@microsoft.com>
---
 drivers/net/hyperv/hyperv_net.h   |  4 +---
 drivers/net/hyperv/netvsc.c       | 22 ++++++++++++++--------
 drivers/net/hyperv/rndis_filter.c |  5 ++---
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 21666df4cd35..5627003bd8b6 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -653,13 +653,11 @@ struct recv_comp_data {
        u32 status;
 };
 
-/* Netvsc Receive Slots Max */
-#define NETVSC_RECVSLOT_MAX (NETVSC_RECEIVE_BUFFER_SIZE / ETH_DATA_LEN + 1)
-
 struct multi_recv_comp {
        void *buf; /* queued receive completions */
        u32 first; /* first data entry */
        u32 next; /* next entry for writing */
+       u32 size; /* number of slots in ring */
 };
 
 struct netvsc_stats {
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 767ff20d659e..56e0721f703c 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -61,16 +61,22 @@ void netvsc_switch_datapath(struct net_device *ndev, bool 
vf)
                               VM_PKT_DATA_INBAND, 0);
 }
 
-static struct netvsc_device *alloc_net_device(void)
+static struct netvsc_device *alloc_net_device(u32 recvslot_max)
 {
        struct netvsc_device *net_device;
+       struct multi_recv_comp *mrc;
 
        net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
        if (!net_device)
                return NULL;
 
-       net_device->chan_table[0].mrc.buf
-               = vzalloc(NETVSC_RECVSLOT_MAX * sizeof(struct recv_comp_data));
+       mrc = &net_device->chan_table[0].mrc;
+       mrc->size = recvslot_max;
+       mrc->buf = vzalloc(recvslot_max * sizeof(struct recv_comp_data));
+       if (!mrc->buf) {
+               kfree(net_device);
+               return NULL;
+       }
 
        init_waitqueue_head(&net_device->wait_drain);
        net_device->destroy = false;
@@ -993,10 +999,10 @@ static inline void count_recv_comp_slot(struct 
netvsc_device *nvdev, u16 q_idx,
        u32 first = mrc->first;
        u32 next = mrc->next;
 
-       *filled = (first > next) ? NETVSC_RECVSLOT_MAX - first + next :
+       *filled = (first > next) ? mrc->size - first + next :
                  next - first;
 
-       *avail = NETVSC_RECVSLOT_MAX - *filled - 1;
+       *avail = mrc->size - *filled - 1;
 }
 
 /* Read the first filled slot, no change to index */
@@ -1022,7 +1028,7 @@ static inline void put_recv_comp_slot(struct 
netvsc_device *nvdev, u16 q_idx)
        struct multi_recv_comp *mrc = &nvdev->chan_table[q_idx].mrc;
        int num_recv;
 
-       mrc->first = (mrc->first + 1) % NETVSC_RECVSLOT_MAX;
+       mrc->first = (mrc->first + 1) % mrc->size;
 
        num_recv = atomic_dec_return(&nvdev->num_outstanding_recvs);
 
@@ -1077,7 +1083,7 @@ static inline struct recv_comp_data *get_recv_comp_slot(
 
        next = mrc->next;
        rcd = mrc->buf + next * sizeof(struct recv_comp_data);
-       mrc->next = (next + 1) % NETVSC_RECVSLOT_MAX;
+       mrc->next = (next + 1) % mrc->size;
 
        atomic_inc(&nvdev->num_outstanding_recvs);
 
@@ -1315,7 +1321,7 @@ int netvsc_device_add(struct hv_device *device,
        struct net_device *ndev = hv_get_drvdata(device);
        struct net_device_context *net_device_ctx = netdev_priv(ndev);
 
-       net_device = alloc_net_device();
+       net_device = alloc_net_device(device_info->recv_buf_size / ETH_DATA_LEN 
+ 1);
        if (!net_device)
                return -ENOMEM;
 
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index f9d5b0b8209a..bfeaa0549f7f 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -996,9 +996,8 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
                return;
 
        nvchan = nvscdev->chan_table + chn_index;
-       nvchan->mrc.buf
-               = vzalloc(NETVSC_RECVSLOT_MAX * sizeof(struct recv_comp_data));
-
+       nvchan->mrc.size = nvscdev->recv_buf_size / ETH_DATA_LEN + 1;
+       nvchan->mrc.buf = vzalloc(nvchan->mrc.size * sizeof(struct 
recv_comp_data));
        if (!nvchan->mrc.buf)
                return;
 
-- 
2.11.0

Reply via email to