diff options
author | Haiyang Zhang <haiyangz@microsoft.com> | 2014-01-27 18:03:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-27 19:40:45 -0500 |
commit | b679ef73edc251f6d200a7dd2396e9fef9e36fc3 (patch) | |
tree | b04daa074ce7083d763eea8daaf4e7d88a61c320 | |
parent | 731073b9c99d46c6b6c01184f67ee6f75fd7a163 (diff) |
hyperv: Add support for physically discontinuous receive buffer
This will allow us to use bigger receive buffer, and prevent allocation failure
due to fragmented memory.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/hv/channel.c | 14 | ||||
-rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 2 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 7 |
3 files changed, 11 insertions, 12 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index cea623c36ae2..69ea36f07b4d 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c | |||
@@ -209,7 +209,6 @@ static int create_gpadl_header(void *kbuffer, u32 size, | |||
209 | { | 209 | { |
210 | int i; | 210 | int i; |
211 | int pagecount; | 211 | int pagecount; |
212 | unsigned long long pfn; | ||
213 | struct vmbus_channel_gpadl_header *gpadl_header; | 212 | struct vmbus_channel_gpadl_header *gpadl_header; |
214 | struct vmbus_channel_gpadl_body *gpadl_body; | 213 | struct vmbus_channel_gpadl_body *gpadl_body; |
215 | struct vmbus_channel_msginfo *msgheader; | 214 | struct vmbus_channel_msginfo *msgheader; |
@@ -219,7 +218,6 @@ static int create_gpadl_header(void *kbuffer, u32 size, | |||
219 | int pfnsum, pfncount, pfnleft, pfncurr, pfnsize; | 218 | int pfnsum, pfncount, pfnleft, pfncurr, pfnsize; |
220 | 219 | ||
221 | pagecount = size >> PAGE_SHIFT; | 220 | pagecount = size >> PAGE_SHIFT; |
222 | pfn = virt_to_phys(kbuffer) >> PAGE_SHIFT; | ||
223 | 221 | ||
224 | /* do we need a gpadl body msg */ | 222 | /* do we need a gpadl body msg */ |
225 | pfnsize = MAX_SIZE_CHANNEL_MESSAGE - | 223 | pfnsize = MAX_SIZE_CHANNEL_MESSAGE - |
@@ -248,7 +246,8 @@ static int create_gpadl_header(void *kbuffer, u32 size, | |||
248 | gpadl_header->range[0].byte_offset = 0; | 246 | gpadl_header->range[0].byte_offset = 0; |
249 | gpadl_header->range[0].byte_count = size; | 247 | gpadl_header->range[0].byte_count = size; |
250 | for (i = 0; i < pfncount; i++) | 248 | for (i = 0; i < pfncount; i++) |
251 | gpadl_header->range[0].pfn_array[i] = pfn+i; | 249 | gpadl_header->range[0].pfn_array[i] = slow_virt_to_phys( |
250 | kbuffer + PAGE_SIZE * i) >> PAGE_SHIFT; | ||
252 | *msginfo = msgheader; | 251 | *msginfo = msgheader; |
253 | *messagecount = 1; | 252 | *messagecount = 1; |
254 | 253 | ||
@@ -301,7 +300,9 @@ static int create_gpadl_header(void *kbuffer, u32 size, | |||
301 | * so the hypervisor gurantees that this is ok. | 300 | * so the hypervisor gurantees that this is ok. |
302 | */ | 301 | */ |
303 | for (i = 0; i < pfncurr; i++) | 302 | for (i = 0; i < pfncurr; i++) |
304 | gpadl_body->pfn[i] = pfn + pfnsum + i; | 303 | gpadl_body->pfn[i] = slow_virt_to_phys( |
304 | kbuffer + PAGE_SIZE * (pfnsum + i)) >> | ||
305 | PAGE_SHIFT; | ||
305 | 306 | ||
306 | /* add to msg header */ | 307 | /* add to msg header */ |
307 | list_add_tail(&msgbody->msglistentry, | 308 | list_add_tail(&msgbody->msglistentry, |
@@ -327,7 +328,8 @@ static int create_gpadl_header(void *kbuffer, u32 size, | |||
327 | gpadl_header->range[0].byte_offset = 0; | 328 | gpadl_header->range[0].byte_offset = 0; |
328 | gpadl_header->range[0].byte_count = size; | 329 | gpadl_header->range[0].byte_count = size; |
329 | for (i = 0; i < pagecount; i++) | 330 | for (i = 0; i < pagecount; i++) |
330 | gpadl_header->range[0].pfn_array[i] = pfn+i; | 331 | gpadl_header->range[0].pfn_array[i] = slow_virt_to_phys( |
332 | kbuffer + PAGE_SIZE * i) >> PAGE_SHIFT; | ||
331 | 333 | ||
332 | *msginfo = msgheader; | 334 | *msginfo = msgheader; |
333 | *messagecount = 1; | 335 | *messagecount = 1; |
@@ -344,7 +346,7 @@ nomem: | |||
344 | * vmbus_establish_gpadl - Estabish a GPADL for the specified buffer | 346 | * vmbus_establish_gpadl - Estabish a GPADL for the specified buffer |
345 | * | 347 | * |
346 | * @channel: a channel | 348 | * @channel: a channel |
347 | * @kbuffer: from kmalloc | 349 | * @kbuffer: from kmalloc or vmalloc |
348 | * @size: page-size multiple | 350 | * @size: page-size multiple |
349 | * @gpadl_handle: some funky thing | 351 | * @gpadl_handle: some funky thing |
350 | */ | 352 | */ |
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index a26eecb1212c..7b594ce3f21d 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
@@ -462,7 +462,7 @@ struct nvsp_message { | |||
462 | 462 | ||
463 | #define NETVSC_MTU 65536 | 463 | #define NETVSC_MTU 65536 |
464 | 464 | ||
465 | #define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*2) /* 2MB */ | 465 | #define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */ |
466 | 466 | ||
467 | #define NETVSC_RECEIVE_BUFFER_ID 0xcafe | 467 | #define NETVSC_RECEIVE_BUFFER_ID 0xcafe |
468 | 468 | ||
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 93b485b96249..03a2c6e17158 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -136,8 +136,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) | |||
136 | 136 | ||
137 | if (net_device->recv_buf) { | 137 | if (net_device->recv_buf) { |
138 | /* Free up the receive buffer */ | 138 | /* Free up the receive buffer */ |
139 | free_pages((unsigned long)net_device->recv_buf, | 139 | vfree(net_device->recv_buf); |
140 | get_order(net_device->recv_buf_size)); | ||
141 | net_device->recv_buf = NULL; | 140 | net_device->recv_buf = NULL; |
142 | } | 141 | } |
143 | 142 | ||
@@ -163,9 +162,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
163 | return -ENODEV; | 162 | return -ENODEV; |
164 | ndev = net_device->ndev; | 163 | ndev = net_device->ndev; |
165 | 164 | ||
166 | net_device->recv_buf = | 165 | net_device->recv_buf = vzalloc(net_device->recv_buf_size); |
167 | (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, | ||
168 | get_order(net_device->recv_buf_size)); | ||
169 | if (!net_device->recv_buf) { | 166 | if (!net_device->recv_buf) { |
170 | netdev_err(ndev, "unable to allocate receive " | 167 | netdev_err(ndev, "unable to allocate receive " |
171 | "buffer of size %d\n", net_device->recv_buf_size); | 168 | "buffer of size %d\n", net_device->recv_buf_size); |