Re: Locking issues in "mmc: rtsx: add support for pre_req and post_req"

2014-04-21 Thread micky

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)

2014-04-21 Thread Haiyang Zhang
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)

2014-04-21 Thread David Miller
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

2014-04-21 Thread Haiyang Zhang
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

2014-04-21 Thread Haiyang Zhang
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

2014-04-21 Thread David Miller
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

2014-04-21 Thread Haiyang Zhang
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

2014-04-21 Thread Haiyang Zhang
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

2014-04-21 Thread Haiyang Zhang


> -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