aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaiyang Zhang <haiyangz@microsoft.com>2011-12-15 16:45:15 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-04 19:13:05 -0500
commit453263421f88b4a7e508c2e7b639c97e99c5b118 (patch)
treeb38aaaccac96fda0b3b6e25c05b0bbbbe7a84567
parent3b148be0df8e45a0259d7e84001cf02e897af614 (diff)
net/hyperv: Remove unnecessary kmap_atomic in netvsc driver
__get_free_pages() doesn't return HI memory, so the memory is always mapped. kmap_atomic() is not necessary here. This patch removes the kmap_atomic() calls and related code for locking and page manipulation. Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/net/hyperv/hyperv_net.h6
-rw-r--r--drivers/net/hyperv/netvsc.c53
-rw-r--r--drivers/net/hyperv/netvsc_drv.c22
-rw-r--r--drivers/net/hyperv/rndis_filter.c21
4 files changed, 10 insertions, 92 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 49b131f71d7a..ff1b5209b45f 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -39,9 +39,6 @@ struct xferpage_packet {
39 u32 count; 39 u32 count;
40}; 40};
41 41
42/* The number of pages which are enough to cover jumbo frame buffer. */
43#define NETVSC_PACKET_MAXPAGE 4
44
45/* 42/*
46 * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame 43 * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
47 * within the RNDIS 44 * within the RNDIS
@@ -77,8 +74,9 @@ struct hv_netvsc_packet {
77 74
78 u32 total_data_buflen; 75 u32 total_data_buflen;
79 /* Points to the send/receive buffer where the ethernet frame is */ 76 /* Points to the send/receive buffer where the ethernet frame is */
77 void *data;
80 u32 page_buf_cnt; 78 u32 page_buf_cnt;
81 struct hv_page_buffer page_buf[NETVSC_PACKET_MAXPAGE]; 79 struct hv_page_buffer page_buf[0];
82}; 80};
83 81
84struct netvsc_device_info { 82struct netvsc_device_info {
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index b6ac152a9bd0..bab627f261c4 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -603,12 +603,10 @@ static void netvsc_receive(struct hv_device *device,
603 struct vmtransfer_page_packet_header *vmxferpage_packet; 603 struct vmtransfer_page_packet_header *vmxferpage_packet;
604 struct nvsp_message *nvsp_packet; 604 struct nvsp_message *nvsp_packet;
605 struct hv_netvsc_packet *netvsc_packet = NULL; 605 struct hv_netvsc_packet *netvsc_packet = NULL;
606 unsigned long start;
607 unsigned long end, end_virtual;
608 /* struct netvsc_driver *netvscDriver; */ 606 /* struct netvsc_driver *netvscDriver; */
609 struct xferpage_packet *xferpage_packet = NULL; 607 struct xferpage_packet *xferpage_packet = NULL;
610 int i, j; 608 int i;
611 int count = 0, bytes_remain = 0; 609 int count = 0;
612 unsigned long flags; 610 unsigned long flags;
613 struct net_device *ndev; 611 struct net_device *ndev;
614 612
@@ -717,53 +715,10 @@ static void netvsc_receive(struct hv_device *device,
717 netvsc_packet->completion.recv.recv_completion_tid = 715 netvsc_packet->completion.recv.recv_completion_tid =
718 vmxferpage_packet->d.trans_id; 716 vmxferpage_packet->d.trans_id;
719 717
718 netvsc_packet->data = (void *)((unsigned long)net_device->
719 recv_buf + vmxferpage_packet->ranges[i].byte_offset);
720 netvsc_packet->total_data_buflen = 720 netvsc_packet->total_data_buflen =
721 vmxferpage_packet->ranges[i].byte_count; 721 vmxferpage_packet->ranges[i].byte_count;
722 netvsc_packet->page_buf_cnt = 1;
723
724 netvsc_packet->page_buf[0].len =
725 vmxferpage_packet->ranges[i].byte_count;
726
727 start = virt_to_phys((void *)((unsigned long)net_device->
728 recv_buf + vmxferpage_packet->ranges[i].byte_offset));
729
730 netvsc_packet->page_buf[0].pfn = start >> PAGE_SHIFT;
731 end_virtual = (unsigned long)net_device->recv_buf
732 + vmxferpage_packet->ranges[i].byte_offset
733 + vmxferpage_packet->ranges[i].byte_count - 1;
734 end = virt_to_phys((void *)end_virtual);
735
736 /* Calculate the page relative offset */
737 netvsc_packet->page_buf[0].offset =
738 vmxferpage_packet->ranges[i].byte_offset &
739 (PAGE_SIZE - 1);
740 if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) {
741 /* Handle frame across multiple pages: */
742 netvsc_packet->page_buf[0].len =
743 (netvsc_packet->page_buf[0].pfn <<
744 PAGE_SHIFT)
745 + PAGE_SIZE - start;
746 bytes_remain = netvsc_packet->total_data_buflen -
747 netvsc_packet->page_buf[0].len;
748 for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) {
749 netvsc_packet->page_buf[j].offset = 0;
750 if (bytes_remain <= PAGE_SIZE) {
751 netvsc_packet->page_buf[j].len =
752 bytes_remain;
753 bytes_remain = 0;
754 } else {
755 netvsc_packet->page_buf[j].len =
756 PAGE_SIZE;
757 bytes_remain -= PAGE_SIZE;
758 }
759 netvsc_packet->page_buf[j].pfn =
760 virt_to_phys((void *)(end_virtual -
761 bytes_remain)) >> PAGE_SHIFT;
762 netvsc_packet->page_buf_cnt++;
763 if (bytes_remain == 0)
764 break;
765 }
766 }
767 722
768 /* Pass it to the upper layer */ 723 /* Pass it to the upper layer */
769 rndis_filter_receive(device, netvsc_packet); 724 rndis_filter_receive(device, netvsc_packet);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 7da85ebd7ac6..b7cbd126f20a 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -251,9 +251,6 @@ int netvsc_recv_callback(struct hv_device *device_obj,
251{ 251{
252 struct net_device *net = dev_get_drvdata(&device_obj->device); 252 struct net_device *net = dev_get_drvdata(&device_obj->device);
253 struct sk_buff *skb; 253 struct sk_buff *skb;
254 void *data;
255 int i;
256 unsigned long flags;
257 struct netvsc_device *net_device; 254 struct netvsc_device *net_device;
258 255
259 net_device = hv_get_drvdata(device_obj); 256 net_device = hv_get_drvdata(device_obj);
@@ -272,27 +269,12 @@ int netvsc_recv_callback(struct hv_device *device_obj,
272 return 0; 269 return 0;
273 } 270 }
274 271
275 /* for kmap_atomic */
276 local_irq_save(flags);
277
278 /* 272 /*
279 * Copy to skb. This copy is needed here since the memory pointed by 273 * Copy to skb. This copy is needed here since the memory pointed by
280 * hv_netvsc_packet cannot be deallocated 274 * hv_netvsc_packet cannot be deallocated
281 */ 275 */
282 for (i = 0; i < packet->page_buf_cnt; i++) { 276 memcpy(skb_put(skb, packet->total_data_buflen), packet->data,
283 data = kmap_atomic(pfn_to_page(packet->page_buf[i].pfn), 277 packet->total_data_buflen);
284 KM_IRQ1);
285 data = (void *)(unsigned long)data +
286 packet->page_buf[i].offset;
287
288 memcpy(skb_put(skb, packet->page_buf[i].len), data,
289 packet->page_buf[i].len);
290
291 kunmap_atomic((void *)((unsigned long)data -
292 packet->page_buf[i].offset), KM_IRQ1);
293 }
294
295 local_irq_restore(flags);
296 278
297 skb->protocol = eth_type_trans(skb, net); 279 skb->protocol = eth_type_trans(skb, net);
298 skb->ip_summed = CHECKSUM_NONE; 280 skb->ip_summed = CHECKSUM_NONE;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 418e7aac229c..da181f9a49d1 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -309,7 +309,6 @@ static void rndis_filter_receive_data(struct rndis_device *dev,
309{ 309{
310 struct rndis_packet *rndis_pkt; 310 struct rndis_packet *rndis_pkt;
311 u32 data_offset; 311 u32 data_offset;
312 int i;
313 312
314 rndis_pkt = &msg->msg.pkt; 313 rndis_pkt = &msg->msg.pkt;
315 314
@@ -322,17 +321,7 @@ static void rndis_filter_receive_data(struct rndis_device *dev,
322 data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; 321 data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
323 322
324 pkt->total_data_buflen -= data_offset; 323 pkt->total_data_buflen -= data_offset;
325 pkt->page_buf[0].offset += data_offset; 324 pkt->data = (void *)((unsigned long)pkt->data + data_offset);
326 pkt->page_buf[0].len -= data_offset;
327
328 /* Drop the 0th page, if rndis data go beyond page boundary */
329 if (pkt->page_buf[0].offset >= PAGE_SIZE) {
330 pkt->page_buf[1].offset = pkt->page_buf[0].offset - PAGE_SIZE;
331 pkt->page_buf[1].len -= pkt->page_buf[1].offset;
332 pkt->page_buf_cnt--;
333 for (i = 0; i < pkt->page_buf_cnt; i++)
334 pkt->page_buf[i] = pkt->page_buf[i+1];
335 }
336 325
337 pkt->is_data_pkt = true; 326 pkt->is_data_pkt = true;
338 327
@@ -367,11 +356,7 @@ int rndis_filter_receive(struct hv_device *dev,
367 return -ENODEV; 356 return -ENODEV;
368 } 357 }
369 358
370 rndis_hdr = (struct rndis_message *)kmap_atomic( 359 rndis_hdr = pkt->data;
371 pfn_to_page(pkt->page_buf[0].pfn), KM_IRQ0);
372
373 rndis_hdr = (void *)((unsigned long)rndis_hdr +
374 pkt->page_buf[0].offset);
375 360
376 /* Make sure we got a valid rndis message */ 361 /* Make sure we got a valid rndis message */
377 if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) && 362 if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) &&
@@ -387,8 +372,6 @@ int rndis_filter_receive(struct hv_device *dev,
387 sizeof(struct rndis_message) : 372 sizeof(struct rndis_message) :
388 rndis_hdr->msg_len); 373 rndis_hdr->msg_len);
389 374
390 kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0);
391
392 dump_rndis_message(dev, &rndis_msg); 375 dump_rndis_message(dev, &rndis_msg);
393 376
394 switch (rndis_msg.ndis_msg_type) { 377 switch (rndis_msg.ndis_msg_type) {