diff options
author | Haiyang Zhang <haiyangz@microsoft.com> | 2011-12-15 16:45:15 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2012-01-04 19:13:05 -0500 |
commit | 453263421f88b4a7e508c2e7b639c97e99c5b118 (patch) | |
tree | b38aaaccac96fda0b3b6e25c05b0bbbbe7a84567 /drivers/net | |
parent | 3b148be0df8e45a0259d7e84001cf02e897af614 (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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 6 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 53 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 22 | ||||
-rw-r--r-- | drivers/net/hyperv/rndis_filter.c | 21 |
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 | ||
84 | struct netvsc_device_info { | 82 | struct 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) { |