RE: [V2 3/7] Drivers: hv: vmbus: add APIs to send/recv hvsock packet and get the r/w-ability

2015-07-16 Thread Dexuan Cui
 -Original Message-
 From: David Miller
 Sent: Thursday, July 16, 2015 12:16
 
 From: Dexuan Cui
 Date: Tue, 14 Jul 2015 02:58:56 -0700
 
  +int vmbus_sendpacket_hvsock(struct vmbus_channel *channel, void *buf,
 u32 len)
  +{
  +   struct vmpacket_descriptor desc;
  +   struct vmpipe_proto_header pipe_hdr;
  +   u32 packetlen;
  +   u32 packetlen_aligned;
  +   struct kvec bufferlist[4];
  +   u64 aligned_data = 0;
  +   int ret;
  +   bool signal = false;
 
 Reverse christmas-tree (longest to shortest line) order these local
 variables, please.
OK.

 
  +EXPORT_SYMBOL(vmbus_sendpacket_hvsock);
 
 EXPORT_SYMBOL_GPL()
Oh, sorry. I'll fix it.
 
  +int vmbus_recvpacket_hvsock(struct vmbus_channel *channel, void *buffer,
  +   u32 bufferlen, u32 *buffer_actual_len)
  +{
  +   struct vmpacket_descriptor *desc;
  +   struct vmpipe_proto_header *pipe_hdr;
  +   u32 packet_len, payload_len;
  +   int ret;
  +   bool signal = false;
 
 Again, please use reverse christmas-tree order.
OK.


  +void vmbus_get_hvsock_rw_status(struct vmbus_channel *channel,
  +  bool *can_read, bool *can_write)
 
 Second line is not properly indented, it should start exactly one
 column after the openning parenthesis on the previous line.
OK.
I didn't realize this issue. Thanks for reminding me!
The patch did pass the check of scripts/checkpatch.pl. :-)
I found scripts/Lindent can detect such kind of issue.
I'll run scripts/Lindent against my code and fix all of them in V3.

  +   hv_get_ringbuffer_availbytes(inring_info,
  +   bytes_avail_toread,
  +   bytes_avail_towrite);
 
 Again, improperly indented.
OK. will fix it.

  +extern int vmbus_sendpacket_hvsock(struct vmbus_channel *channel,
  +   void *buf, u32 len);
  +
 
 Likewise.
OK. will fix it.

  +extern int vmbus_recvpacket_hvsock(struct vmbus_channel *channel, void
 *buffer,
  +   u32 bufferlen, u32 *buffer_actual_len);
  +
  +extern void vmbus_get_hvsock_rw_status(struct vmbus_channel *channel,
  +  bool *can_read, bool *can_write);
 
 Likewise.
OK. will fix it.

-- Dexuan
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [V2 3/7] Drivers: hv: vmbus: add APIs to send/recv hvsock packet and get the r/w-ability

2015-07-15 Thread David Miller
From: Dexuan Cui de...@microsoft.com
Date: Tue, 14 Jul 2015 02:58:56 -0700

 +int vmbus_sendpacket_hvsock(struct vmbus_channel *channel, void *buf, u32 
 len)
 +{
 + struct vmpacket_descriptor desc;
 + struct vmpipe_proto_header pipe_hdr;
 + u32 packetlen;
 + u32 packetlen_aligned;
 + struct kvec bufferlist[4];
 + u64 aligned_data = 0;
 + int ret;
 + bool signal = false;

Reverse christmas-tree (longest to shortest line) order these local
variables, please.

 +EXPORT_SYMBOL(vmbus_sendpacket_hvsock);

EXPORT_SYMBOL_GPL()

 +int vmbus_recvpacket_hvsock(struct vmbus_channel *channel, void *buffer,
 + u32 bufferlen, u32 *buffer_actual_len)
 +{
 + struct vmpacket_descriptor *desc;
 + struct vmpipe_proto_header *pipe_hdr;
 + u32 packet_len, payload_len;
 + int ret;
 + bool signal = false;

Again, please use reverse christmas-tree order.

 +void vmbus_get_hvsock_rw_status(struct vmbus_channel *channel,
 +bool *can_read, bool *can_write)

Second line is not properly indented, it should start exactly one
column after the openning parenthesis on the previous line.

 + hv_get_ringbuffer_availbytes(inring_info,
 + bytes_avail_toread,
 + bytes_avail_towrite);

Again, improperly indented.

 +extern int vmbus_sendpacket_hvsock(struct vmbus_channel *channel,
 + void *buf, u32 len);
 +

Likewise.

 +extern int vmbus_recvpacket_hvsock(struct vmbus_channel *channel, void 
 *buffer,
 + u32 bufferlen, u32 *buffer_actual_len);
 +
 +extern void vmbus_get_hvsock_rw_status(struct vmbus_channel *channel,
 +bool *can_read, bool *can_write);

Likewise.
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[V2 3/7] Drivers: hv: vmbus: add APIs to send/recv hvsock packet and get the r/w-ability

2015-07-14 Thread Dexuan Cui
This will be used by the coming net/hvsock driver.

Signed-off-by: Dexuan Cui de...@microsoft.com
---
 drivers/hv/channel.c  | 131 ++
 drivers/hv/hyperv_vmbus.h |   4 ++
 drivers/hv/ring_buffer.c  |  14 +
 include/linux/hyperv.h|  33 
 4 files changed, 182 insertions(+)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index b09d1b7..9c3727a 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -758,6 +758,53 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel 
*channel,
 EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer_ctl);
 
 /*
+ * vmbus_sendpacket_hvsock - Send the hvsock payload 'buf' into the vmbus
+ * ringbuffer
+ */
+int vmbus_sendpacket_hvsock(struct vmbus_channel *channel, void *buf, u32 len)
+{
+   struct vmpacket_descriptor desc;
+   struct vmpipe_proto_header pipe_hdr;
+   u32 packetlen;
+   u32 packetlen_aligned;
+   struct kvec bufferlist[4];
+   u64 aligned_data = 0;
+   int ret;
+   bool signal = false;
+
+   packetlen = HVSOCK_HEADER_LEN + len;
+   packetlen_aligned = ALIGN(packetlen, sizeof(u64));
+
+   /* Setup the descriptor */
+   desc.type = VM_PKT_DATA_INBAND;
+   /* in 8-bytes granularity */
+   desc.offset8 = sizeof(struct vmpacket_descriptor)  3;
+   desc.len8 = (u16)(packetlen_aligned  3);
+   desc.flags = 0;
+   desc.trans_id = 0;
+
+   pipe_hdr.pkt_type = 1;
+   pipe_hdr.data_size = len;
+
+   bufferlist[0].iov_base = desc;
+   bufferlist[0].iov_len  = sizeof(struct vmpacket_descriptor);
+   bufferlist[1].iov_base = pipe_hdr;
+   bufferlist[1].iov_len  = sizeof(struct vmpipe_proto_header);
+   bufferlist[2].iov_base = buf;
+   bufferlist[2].iov_len  = len;
+   bufferlist[3].iov_base = aligned_data;
+   bufferlist[3].iov_len  = packetlen_aligned - packetlen;
+
+   ret = hv_ringbuffer_write(channel-outbound, bufferlist, 4, signal);
+
+   if (ret == 0  signal)
+   vmbus_setevent(channel);
+
+   return ret;
+}
+EXPORT_SYMBOL(vmbus_sendpacket_hvsock);
+
+/*
  * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
  * packets using a GPADL Direct packet type.
  */
@@ -978,3 +1025,87 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, 
void *buffer,
return ret;
 }
 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
+
+/*
+ * vmbus_recvpacket_hvsock - Receive the hvsock payload from the vmbus
+ * ringbuffer into the 'buffer'.
+ */
+int vmbus_recvpacket_hvsock(struct vmbus_channel *channel, void *buffer,
+   u32 bufferlen, u32 *buffer_actual_len)
+{
+   struct vmpacket_descriptor *desc;
+   struct vmpipe_proto_header *pipe_hdr;
+   u32 packet_len, payload_len;
+   int ret;
+   bool signal = false;
+
+   *buffer_actual_len = 0;
+
+   if (bufferlen  HVSOCK_HEADER_LEN)
+   return -ENOBUFS;
+
+   ret = hv_ringbuffer_peek(channel-inbound, buffer,
+HVSOCK_HEADER_LEN);
+   if (ret != 0)
+   return 0;
+
+   desc = (struct vmpacket_descriptor *)buffer;
+   packet_len = desc-len8  3;
+   if (desc-type != VM_PKT_DATA_INBAND ||
+   desc-offset8 != (sizeof(*desc) / 8) ||
+   packet_len  HVSOCK_HEADER_LEN)
+   return -EIO;
+
+   pipe_hdr = (struct vmpipe_proto_header *)(desc + 1);
+   payload_len = pipe_hdr-data_size;
+
+   if (pipe_hdr-pkt_type != 1 || payload_len == 0)
+   return -EIO;
+
+   if (HVSOCK_PKT_LEN(payload_len) != packet_len + PREV_INDICES_LEN)
+   return -EIO;
+
+   if (bufferlen  packet_len - HVSOCK_HEADER_LEN)
+   return -ENOBUFS;
+
+   /* Copy over the hvsock payload to the user buffer */
+   ret = hv_ringbuffer_read(channel-inbound, buffer,
+packet_len - HVSOCK_HEADER_LEN,
+HVSOCK_HEADER_LEN, signal);
+   if (ret != 0)
+   return ret;
+
+   *buffer_actual_len = payload_len;
+
+   if (signal)
+   vmbus_setevent(channel);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vmbus_recvpacket_hvsock);
+
+/*
+ * vmbus_get_hvsock_rw_status - can the ringbuffer be read/written?
+ */
+void vmbus_get_hvsock_rw_status(struct vmbus_channel *channel,
+  bool *can_read, bool *can_write)
+{
+   u32 avl_read_bytes, avl_write_bytes, dummy;
+
+   if (can_read != NULL) {
+   hv_get_ringbuffer_space(channel-inbound, avl_read_bytes,
+   dummy);
+   *can_read = avl_read_bytes = HVSOCK_MIN_PKT_LEN;
+   }
+
+   /* We write into the ringbuffer only when we're able to write a
+* a payload of 4096 bytes (the actual written payload's length may be
+* less than 4096).
+*/
+   if (can_write != NULL) {
+