Re: Locking issues in "mmc: rtsx: add support for pre_req and post_req"
Hi Peter, I'm considering not using spinlock to get it work and will resend the patch later. Thank you. Best Regards. micky On 04/19/2014 07:13 AM, Peter Wu wrote: So, I reverted c42deffd5b53c9e583d83c7964854ede2f12410d ("mmc: rtsx: add support for pre_req and post_req") on top of v3.15-rc1-49-g10ec34f and the hang issue went away. There is something that is possibly problematic. All three tasklets (cmd, data, finish) try to spinlock on host->lock. According to the tasklets documentation[1], they always run at interrupts (i.e., at any time, possibly right after tasklet_schedule if I got this right?). These tasklets however do get scheduled *under* the host->lock which will cause a deadlock. This proposed patch ("mmc: rtsx: fix possible circular locking dependency") fixes the issue for sd_isr_done_transfer, but there are others: 1. sd_request_timeout: 125 spin_lock_irqsave(&host->lock, flags); ... 139 out: 140 tasklet_schedule(&host->finish_tasklet); // <-- 141 spin_unlock_irqrestore(&host->lock, flags); 2. sd_get_rsp (cmd_tasklet!): 429 spin_lock_irqsave(&host->lock, flags); ... 506 tasklet_schedule(&host->finish_tasklet); // <-- 507 spin_unlock_irqrestore(&host->lock, flags); 3. sd_finish_multi_rw (data_tasklet!): 657 spin_lock_irqsave(&host->lock, flags); ... 684 tasklet_schedule(&host->finish_tasklet); // <-- 685 spin_unlock_irqrestore(&host->lock, flags); 4. sdmmc_request: 921 mutex_lock(&pcr->pcr_mutex); 922 spin_lock_irqsave(&host->lock, flags); ... 967 tasklet_schedule(&host->finish_tasklet); // <-- 968 spin_unlock_irqrestore(&host->lock, flags); 5. rtsx_pci_sdmmc_drv_remove: 1526 spin_lock_irqsave(&host->lock, flags); 1527 if (host->mrq) { ... 1541 tasklet_schedule(&host->finish_tasklet); // <-- 1542 } 1543 spin_unlock_irqrestore(&host->lock, flags); 1544 1545 del_timer_sync(&host->timer); 1546 tasklet_kill(&host->cmd_tasklet); 1547 tasklet_kill(&host->data_tasklet); 1548 tasklet_kill(&host->finish_tasklet); // <-- pcr_mutex (un)locking: - gets locked in sdmmc_request - gets unlocked in sd_finish_request (finish_tasklet). - gets locked/unlocked in sdmmc_set_ios - gets locked/unlocked in sdmmc_get_ro - gets locked/unlocked in sdmmc_get_cd - gets locked/unlocked in sdmmc_switch_voltage - gets locked/unlocked in sdmmc_execute_tuning finish_tasklet (sd_finish_request()) gets scheduled in: - sd_request_timeout (under host->lock; called on timer expiration) - error path of sd_send_cmd - get_rsp (cmd_tasklet; under host->lock) - error path of sd_start_multi_rw (after mod timer) - sd_finish_multi_rw (under host->lock) - sdmmc_request (under host->lock in error path; without host->lock elsewhere) - rtsx_pci_sdmmc_drv_remove (under host->lock) sd_request_timeout (timer) related: - deleted in sd_finish_request under host->lock (also assumes pcr_mutex) - sd_send_cmd (timer set with 100ms timeout, not called in error path) - sd_start_multi_rw (timeout set to 10 HZ, called before error path is checked in which finish_tasklet gets scheduled) Note: sd_request_timeout claims+releases host->lock. If I understand it correctly, host->lock is responsible for protecting the realtek_pci_sdmmc structure. Why is tasklet_schedule() on the same lock? Shouldn't the above five tasklet_schedule calls be moved outside the lock? Will it be problematic if the same tasklet gets executed multiple times (if that is possible?). Does it really need that much locking? dw_mmc.c also implements pre_req, but uses tasklets without needing to lock anything. Kind regards, Peter [1]: http://www.makelinux.net/ldd3/chp-7-sect-5 On Friday 18 April 2014 16:00:53 Peter Wu wrote: On Wednesday 16 April 2014 09:38:44 micky_ch...@realsil.com.cn wrote: From: Micky Ching To avoid dead lock, we need make sure host->lock is always acquire before pcr->lock. But in irq handler, we acquired pcr->lock in rtsx mfd driver, and sd_isr_done_transfer() is called during pcr->lock already acquired. Since in sd_isr_done_transfer() the only work we do is schdule tasklet, the cmd_tasklet and data_tasklet never conflict, so it is safe to remove spin_lock() here. Signed-off-by: Micky Ching --- drivers/mmc/host/rtsx_pci_sdmmc.c |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) This patch came from https://lkml.kernel.org/r/534de1d7.3000...@realsil.com.cn ("Re: rtsx_pci_sdmmc lockdep splat"). With v3.15-rc1-49-g10ec34f, I have a hung machine when inserting a SD card. lockdep was not enabled for the kernel, I have not bisected yet. This patch on top of that kernel version does not help (tested by rmmod rtsx_pci_sdmmc and insmod the patched one). Console (as typed over from a picture, sorry for any typos): WARNING: CPU: 1 PID: 0 at kernel/l
[PATCH net-next, v4] hyperv: Add support for virtual Receive Side Scaling (vRSS)
This feature allows multiple channels to be used by each virtual NIC. It is available on Hyper-V host 2012 R2. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan --- drivers/net/hyperv/hyperv_net.h | 110 +- drivers/net/hyperv/netvsc.c | 136 +- drivers/net/hyperv/netvsc_drv.c | 103 +++- drivers/net/hyperv/rndis_filter.c | 189 - 4 files changed, 504 insertions(+), 34 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index d18f711d..57eb3f9 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -28,6 +28,96 @@ #include #include +/* RSS related */ +#define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203 /* query only */ +#define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204 /* query and set */ + +#define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88 +#define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89 + +#define NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2 +#define NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2 + +struct ndis_obj_header { + u8 type; + u8 rev; + u16 size; +} __packed; + +/* ndis_recv_scale_cap/cap_flag */ +#define NDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x0100 +#define NDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x0200 +#define NDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x0400 +#define NDIS_RSS_CAPS_USING_MSI_X 0x0800 +#define NDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x1000 +#define NDIS_RSS_CAPS_SUPPORTS_MSI_X 0x2000 +#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x0100 +#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x0200 +#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x0400 + +struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */ + struct ndis_obj_header hdr; + u32 cap_flag; + u32 num_int_msg; + u32 num_recv_que; + u16 num_indirect_tabent; +} __packed; + + +/* ndis_recv_scale_param flags */ +#define NDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001 +#define NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED0x0002 +#define NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004 +#define NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008 +#define NDIS_RSS_PARAM_FLAG_DISABLE_RSS0x0010 + +/* Hash info bits */ +#define NDIS_HASH_FUNC_TOEPLITZ 0x0001 +#define NDIS_HASH_IPV4 0x0100 +#define NDIS_HASH_TCP_IPV4 0x0200 +#define NDIS_HASH_IPV6 0x0400 +#define NDIS_HASH_IPV6_EX 0x0800 +#define NDIS_HASH_TCP_IPV6 0x1000 +#define NDIS_HASH_TCP_IPV6_EX 0x2000 + +#define NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4) +#define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40 + +#define ITAB_NUM 128 +#define HASH_KEYLEN NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 +extern u8 netvsc_hash_key[]; + +struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */ + struct ndis_obj_header hdr; + + /* Qualifies the rest of the information */ + u16 flag; + + /* The base CPU number to do receive processing. not used */ + u16 base_cpu_number; + + /* This describes the hash function and type being enabled */ + u32 hashinfo; + + /* The size of indirection table array */ + u16 indirect_tabsize; + + /* The offset of the indirection table from the beginning of this +* structure +*/ + u32 indirect_taboffset; + + /* The size of the hash secret key */ + u16 hashkey_size; + + /* The offset of the secret key from the beginning of this structure */ + u32 kashkey_offset; + + u32 processor_masks_offset; + u32 num_processor_masks; + u32 processor_masks_entry_size; +}; + /* Fwd declaration */ struct hv_netvsc_packet; struct ndis_tcp_ip_checksum_info; @@ -39,6 +129,8 @@ struct xferpage_packet { /* # of netvsc packets this xfer packet contains */ u32 count; + + struct vmbus_channel *channel; }; /* @@ -54,6 +146,9 @@ struct hv_netvsc_packet { bool is_data_pkt; u16 vlan_tci; + u16 q_idx; + struct vmbus_channel *channel; + /* * Valid only for receives when we break a xfer page packet * into multiple netvsc packets @@ -120,6 +215,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, int netvsc_recv_callback(struct hv_device *device_obj, struct hv_netvsc_packet *packet, struct ndis_tcp_ip_checksum_info *csum_info); +void netvsc_channel_cb(void *context); int rndis_filter_open(struct hv_device *dev); int rndis_filter_close(struct hv_device *dev); int rndis_filter_device_add(struct hv_device *dev, @@ -522,6 +618,8 @@ struct nvsp_message { #define NETVSC_PACKET_SIZE 2048 +#define VRSS_SEND_TAB_SIZE 16 + /* Per netvsc channel-specific */ struct netvsc_
Re: [PATCH net-next,v4] hyperv: Add support for virtual Receive Side Scaling (vRSS)
From: Haiyang Zhang Date: Mon, 21 Apr 2014 10:20:28 -0700 > This feature allows multiple channels to be used by each virtual NIC. > It is available on Hyper-V host 2012 R2. > > Signed-off-by: Haiyang Zhang > Reviewed-by: K. Y. Srinivasan Applied, th anks. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH net-next,2/2] hyperv: Simplify the send_completion variables
The union contains only one member now, so we use the variables in it directly. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan --- drivers/net/hyperv/hyperv_net.h | 10 +++--- drivers/net/hyperv/netvsc.c |7 +++ drivers/net/hyperv/netvsc_drv.c |8 drivers/net/hyperv/rndis_filter.c |2 +- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index a1af0f7..d1f7826 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -136,13 +136,9 @@ struct hv_netvsc_packet { u16 q_idx; struct vmbus_channel *channel; - union { - struct { - u64 send_completion_tid; - void *send_completion_ctx; - void (*send_completion)(void *context); - } send; - } completion; + u64 send_completion_tid; + void *send_completion_ctx; + void (*send_completion)(void *context); /* This points to the memory after page_buf */ struct rndis_message *rndis_msg; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index b103347..bbee446 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -479,9 +479,8 @@ static void netvsc_send_completion(struct netvsc_device *net_device, if (nvsc_packet) { q_idx = nvsc_packet->q_idx; channel = nvsc_packet->channel; - nvsc_packet->completion.send.send_completion( - nvsc_packet->completion.send. - send_completion_ctx); + nvsc_packet->send_completion(nvsc_packet-> +send_completion_ctx); } num_outstanding_sends = @@ -534,7 +533,7 @@ int netvsc_send(struct hv_device *device, 0x; sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0; - if (packet->completion.send.send_completion) + if (packet->send_completion) req_id = (ulong)packet; else req_id = 0; diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 8f6d53a..c76b665 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -235,7 +235,7 @@ static void netvsc_xmit_completion(void *context) { struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; struct sk_buff *skb = (struct sk_buff *) - (unsigned long)packet->completion.send.send_completion_tid; + (unsigned long)packet->send_completion_tid; kfree(packet); @@ -425,9 +425,9 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) (num_data_pgs * sizeof(struct hv_page_buffer))); /* Set the completion routine */ - packet->completion.send.send_completion = netvsc_xmit_completion; - packet->completion.send.send_completion_ctx = packet; - packet->completion.send.send_completion_tid = (unsigned long)skb; + packet->send_completion = netvsc_xmit_completion; + packet->send_completion_ctx = packet; + packet->send_completion_tid = (unsigned long)skb; isvlan = packet->vlan_tci & VLAN_TAG_PRESENT; diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 48f5a0f..99c527a 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -236,7 +236,7 @@ static int rndis_filter_send_request(struct rndis_device *dev, packet->page_buf[0].len; } - packet->completion.send.send_completion = NULL; + packet->send_completion = NULL; ret = netvsc_send(dev->net_dev->dev, packet); return ret; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH net-next,1/2] hyperv: Remove recv_pkt_list and lock
Removed recv_pkt_list and lock, and updated related code, so that the locking overhead is reduced especially when multiple channels are in use. The recv_pkt_list isn't actually necessary because the packets are processed sequentially in each channel. It has been replaced by a local variable, and the related lock for this list is also removed. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan --- drivers/net/hyperv/hyperv_net.h | 33 --- drivers/net/hyperv/netvsc.c | 174 +++-- drivers/net/hyperv/netvsc_drv.c |2 +- drivers/net/hyperv/rndis_filter.c |2 - 4 files changed, 13 insertions(+), 198 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 57eb3f9..a1af0f7 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -119,27 +119,14 @@ struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */ }; /* Fwd declaration */ -struct hv_netvsc_packet; struct ndis_tcp_ip_checksum_info; -/* Represent the xfer page packet which contains 1 or more netvsc packet */ -struct xferpage_packet { - struct list_head list_ent; - u32 status; - - /* # of netvsc packets this xfer packet contains */ - u32 count; - - struct vmbus_channel *channel; -}; - /* * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame * within the RNDIS */ struct hv_netvsc_packet { /* Bookkeeping stuff */ - struct list_head list_ent; u32 status; struct hv_device *device; @@ -149,19 +136,8 @@ struct hv_netvsc_packet { u16 q_idx; struct vmbus_channel *channel; - /* -* Valid only for receives when we break a xfer page packet -* into multiple netvsc packets -*/ - struct xferpage_packet *xfer_page_pkt; - union { struct { - u64 recv_completion_tid; - void *recv_completion_ctx; - void (*recv_completion)(void *context); - } recv; - struct { u64 send_completion_tid; void *send_completion_ctx; void (*send_completion)(void *context); @@ -613,9 +589,6 @@ struct nvsp_message { #define NETVSC_RECEIVE_BUFFER_ID 0xcafe -/* Preallocated receive packets */ -#define NETVSC_RECEIVE_PACKETLIST_COUNT256 - #define NETVSC_PACKET_SIZE 2048 #define VRSS_SEND_TAB_SIZE 16 @@ -630,12 +603,6 @@ struct netvsc_device { wait_queue_head_t wait_drain; bool start_remove; bool destroy; - /* -* List of free preallocated hv_netvsc_packet to represent receive -* packet -*/ - struct list_head recv_pkt_list; - spinlock_t recv_pkt_list_lock; /* Receive buffer allocated by us but manages by NetVSP */ void *recv_buf; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index e7e77f1..b103347 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -387,7 +387,6 @@ static void netvsc_disconnect_vsp(struct netvsc_device *net_device) int netvsc_device_remove(struct hv_device *device) { struct netvsc_device *net_device; - struct hv_netvsc_packet *netvsc_packet, *pos; unsigned long flags; net_device = hv_get_drvdata(device); @@ -416,12 +415,6 @@ int netvsc_device_remove(struct hv_device *device) vmbus_close(device->channel); /* Release all resources */ - list_for_each_entry_safe(netvsc_packet, pos, -&net_device->recv_pkt_list, list_ent) { - list_del(&netvsc_packet->list_ent); - kfree(netvsc_packet); - } - if (net_device->sub_cb_buf) vfree(net_device->sub_cb_buf); @@ -641,62 +634,6 @@ retry_send_cmplt: } } -/* Send a receive completion packet to RNDIS device (ie NetVsp) */ -static void netvsc_receive_completion(void *context) -{ - struct hv_netvsc_packet *packet = context; - struct hv_device *device = packet->device; - struct vmbus_channel *channel; - struct netvsc_device *net_device; - u64 transaction_id = 0; - bool fsend_receive_comp = false; - unsigned long flags; - struct net_device *ndev; - u32 status = NVSP_STAT_NONE; - - /* -* Even though it seems logical to do a GetOutboundNetDevice() here to -* send out receive completion, we are using GetInboundNetDevice() -* since we may have disable outbound traffic already. -*/ - net_device = get_inbound_net_device(device); - if (!net_device) - return; - ndev = net_device->ndev; - - /* Overloading use of the lock. */ - spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); - - if (packet->status !
Re: [PATCH net-next,1/2] hyperv: Remove recv_pkt_list and lock
From: Haiyang Zhang Date: Mon, 21 Apr 2014 12:26:15 -0700 > @@ -401,8 +401,6 @@ static void rndis_filter_receive_data(struct rndis_device > *dev, > pkt->total_data_buflen = rndis_pkt->data_len; > pkt->data = (void *)((unsigned long)pkt->data + data_offset); > > - pkt->is_data_pkt = true; > - > vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO); > if (vlan) { > pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid | This part of your change is not explained at all in your commit message. Please resubmit this series with this hunk properly described and accounted for. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH net-next,v2,1/2] hyperv: Remove recv_pkt_list and lock
Removed recv_pkt_list and lock, and updated related code, so that the locking overhead is reduced especially when multiple channels are in use. The recv_pkt_list isn't actually necessary because the packets are processed sequentially in each channel. It has been replaced by a local variable, and the related lock for this list is also removed. The is_data_pkt field is not used in receive path, so its assignment is cleaned up. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan --- drivers/net/hyperv/hyperv_net.h | 33 --- drivers/net/hyperv/netvsc.c | 174 +++-- drivers/net/hyperv/netvsc_drv.c |2 +- drivers/net/hyperv/rndis_filter.c |2 - 4 files changed, 13 insertions(+), 198 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 57eb3f9..a1af0f7 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -119,27 +119,14 @@ struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */ }; /* Fwd declaration */ -struct hv_netvsc_packet; struct ndis_tcp_ip_checksum_info; -/* Represent the xfer page packet which contains 1 or more netvsc packet */ -struct xferpage_packet { - struct list_head list_ent; - u32 status; - - /* # of netvsc packets this xfer packet contains */ - u32 count; - - struct vmbus_channel *channel; -}; - /* * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame * within the RNDIS */ struct hv_netvsc_packet { /* Bookkeeping stuff */ - struct list_head list_ent; u32 status; struct hv_device *device; @@ -149,19 +136,8 @@ struct hv_netvsc_packet { u16 q_idx; struct vmbus_channel *channel; - /* -* Valid only for receives when we break a xfer page packet -* into multiple netvsc packets -*/ - struct xferpage_packet *xfer_page_pkt; - union { struct { - u64 recv_completion_tid; - void *recv_completion_ctx; - void (*recv_completion)(void *context); - } recv; - struct { u64 send_completion_tid; void *send_completion_ctx; void (*send_completion)(void *context); @@ -613,9 +589,6 @@ struct nvsp_message { #define NETVSC_RECEIVE_BUFFER_ID 0xcafe -/* Preallocated receive packets */ -#define NETVSC_RECEIVE_PACKETLIST_COUNT256 - #define NETVSC_PACKET_SIZE 2048 #define VRSS_SEND_TAB_SIZE 16 @@ -630,12 +603,6 @@ struct netvsc_device { wait_queue_head_t wait_drain; bool start_remove; bool destroy; - /* -* List of free preallocated hv_netvsc_packet to represent receive -* packet -*/ - struct list_head recv_pkt_list; - spinlock_t recv_pkt_list_lock; /* Receive buffer allocated by us but manages by NetVSP */ void *recv_buf; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index e7e77f1..b103347 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -387,7 +387,6 @@ static void netvsc_disconnect_vsp(struct netvsc_device *net_device) int netvsc_device_remove(struct hv_device *device) { struct netvsc_device *net_device; - struct hv_netvsc_packet *netvsc_packet, *pos; unsigned long flags; net_device = hv_get_drvdata(device); @@ -416,12 +415,6 @@ int netvsc_device_remove(struct hv_device *device) vmbus_close(device->channel); /* Release all resources */ - list_for_each_entry_safe(netvsc_packet, pos, -&net_device->recv_pkt_list, list_ent) { - list_del(&netvsc_packet->list_ent); - kfree(netvsc_packet); - } - if (net_device->sub_cb_buf) vfree(net_device->sub_cb_buf); @@ -641,62 +634,6 @@ retry_send_cmplt: } } -/* Send a receive completion packet to RNDIS device (ie NetVsp) */ -static void netvsc_receive_completion(void *context) -{ - struct hv_netvsc_packet *packet = context; - struct hv_device *device = packet->device; - struct vmbus_channel *channel; - struct netvsc_device *net_device; - u64 transaction_id = 0; - bool fsend_receive_comp = false; - unsigned long flags; - struct net_device *ndev; - u32 status = NVSP_STAT_NONE; - - /* -* Even though it seems logical to do a GetOutboundNetDevice() here to -* send out receive completion, we are using GetInboundNetDevice() -* since we may have disable outbound traffic already. -*/ - net_device = get_inbound_net_device(device); - if (!net_device) - return; - ndev = net_device->ndev; - - /* Overloading use of the lock. */ - spin_
[PATCH net-next, v2, 2/2] hyperv: Simplify the send_completion variables
The union contains only one member now, so we use the variables in it directly. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan --- drivers/net/hyperv/hyperv_net.h | 10 +++--- drivers/net/hyperv/netvsc.c |7 +++ drivers/net/hyperv/netvsc_drv.c |8 drivers/net/hyperv/rndis_filter.c |2 +- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index a1af0f7..d1f7826 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -136,13 +136,9 @@ struct hv_netvsc_packet { u16 q_idx; struct vmbus_channel *channel; - union { - struct { - u64 send_completion_tid; - void *send_completion_ctx; - void (*send_completion)(void *context); - } send; - } completion; + u64 send_completion_tid; + void *send_completion_ctx; + void (*send_completion)(void *context); /* This points to the memory after page_buf */ struct rndis_message *rndis_msg; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index b103347..bbee446 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -479,9 +479,8 @@ static void netvsc_send_completion(struct netvsc_device *net_device, if (nvsc_packet) { q_idx = nvsc_packet->q_idx; channel = nvsc_packet->channel; - nvsc_packet->completion.send.send_completion( - nvsc_packet->completion.send. - send_completion_ctx); + nvsc_packet->send_completion(nvsc_packet-> +send_completion_ctx); } num_outstanding_sends = @@ -534,7 +533,7 @@ int netvsc_send(struct hv_device *device, 0x; sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0; - if (packet->completion.send.send_completion) + if (packet->send_completion) req_id = (ulong)packet; else req_id = 0; diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 8f6d53a..c76b665 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -235,7 +235,7 @@ static void netvsc_xmit_completion(void *context) { struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; struct sk_buff *skb = (struct sk_buff *) - (unsigned long)packet->completion.send.send_completion_tid; + (unsigned long)packet->send_completion_tid; kfree(packet); @@ -425,9 +425,9 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) (num_data_pgs * sizeof(struct hv_page_buffer))); /* Set the completion routine */ - packet->completion.send.send_completion = netvsc_xmit_completion; - packet->completion.send.send_completion_ctx = packet; - packet->completion.send.send_completion_tid = (unsigned long)skb; + packet->send_completion = netvsc_xmit_completion; + packet->send_completion_ctx = packet; + packet->send_completion_tid = (unsigned long)skb; isvlan = packet->vlan_tci & VLAN_TAG_PRESENT; diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 48f5a0f..99c527a 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -236,7 +236,7 @@ static int rndis_filter_send_request(struct rndis_device *dev, packet->page_buf[0].len; } - packet->completion.send.send_completion = NULL; + packet->send_completion = NULL; ret = netvsc_send(dev->net_dev->dev, packet); return ret; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
RE: [PATCH net-next,1/2] hyperv: Remove recv_pkt_list and lock
> -Original Message- > From: David Miller [mailto:da...@davemloft.net] > Sent: Monday, April 21, 2014 2:57 PM > To: Haiyang Zhang > Cc: net...@vger.kernel.org; KY Srinivasan; o...@aepfle.de; > jasow...@redhat.com; linux-ker...@vger.kernel.org; driverdev- > de...@linuxdriverproject.org > Subject: Re: [PATCH net-next,1/2] hyperv: Remove recv_pkt_list and lock > > From: Haiyang Zhang > Date: Mon, 21 Apr 2014 12:26:15 -0700 > > > @@ -401,8 +401,6 @@ static void rndis_filter_receive_data(struct > rndis_device *dev, > > pkt->total_data_buflen = rndis_pkt->data_len; > > pkt->data = (void *)((unsigned long)pkt->data + data_offset); > > > > - pkt->is_data_pkt = true; > > - > > vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO); > > if (vlan) { > > pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid | > > This part of your change is not explained at all in your commit message. > > Please resubmit this series with this hunk properly described and accounted > for. I have updated the description and re-send them. Thanks, - Haiyang ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel