diff --git a/include/net/af_hvsock.h b/include/net/af_hvsock.h index 20d23d5..e7a8a3a 100644 --- a/include/net/af_hvsock.h +++ b/include/net/af_hvsock.h @@ -5,30 +5,39 @@ #include #include -/* The host side's design of the feature requires 5 exact pages for recv/send - * rings respectively -- this is suboptimal considering memory consumption, - * however unluckily we have to live with it, before the host comes up with - * a better new design in the future. +/* The host side's design of the feature requires 5 exact 4KB pages for + * recv/send rings respectively -- this is suboptimal considering memory + * consumption, however unluckily we have to live with it, before the + * host comes up with a better design in the future. */ -#define RINGBUFFER_HVSOCK_RCV_SIZE (PAGE_SIZE * 5) -#define RINGBUFFER_HVSOCK_SND_SIZE (PAGE_SIZE * 5) +#define PAGE_SIZE_4K 4096 +#define RINGBUFFER_HVSOCK_RCV_SIZE (PAGE_SIZE_4K * 5) +#define RINGBUFFER_HVSOCK_SND_SIZE (PAGE_SIZE_4K * 5) -#define sk_to_hvsock(__sk) ((struct hvsock_sock *)(__sk)) -#define hvsock_to_sk(__hvsk) ((struct sock *)(__hvsk)) - -/* The MTU is 16KB per the host side's design. */ +/* The MTU is 16KB per the host side's design. + * In future, the buffer can be elimiated when we switch to use the coming + * new VMBus ringbuffer "in-place consumption" APIs, by which we can + * directly copy data from VMBus ringbuffer into the userspace buffer. + */ +#define HVSOCK_MTU_SIZE (1024 * 16) struct hvsock_recv_buf { unsigned int data_len; unsigned int data_offset; struct vmpipe_proto_header hdr; - u8 buf[PAGE_SIZE * 4]; + u8 buf[HVSOCK_MTU_SIZE]; }; -/* We send at most 4KB payload per VMBus packet. */ +/* In the VM, actually we can send up to HVSOCK_MTU_SIZE bytes of payload, + * but for now let's use a smaller size to minimize the dynamically-allocated + * buffer. Note: the buffer can be elimiated in future when we add new VMBus + * ringbuffer APIs that allow us to directly copy data from userspace buf to + * VMBus ringbuffer. + */ +#define HVSOCK_MAX_SND_SIZE_BY_VM (1024 * 4) struct hvsock_send_buf { struct vmpipe_proto_header hdr; - u8 buf[PAGE_SIZE]; + u8 buf[HVSOCK_MAX_SND_SIZE_BY_VM]; }; struct hvsock_sock { @@ -56,4 +65,14 @@ struct hvsock_sock { struct hvsock_recv_buf *recv; }; +static inline struct hvsock_sock *sk_to_hvsock(struct sock *sk) +{ + return (struct hvsock_sock *)sk; +} + +static inline struct sock *hvsock_to_sk(struct hvsock_sock *hvsk) +{ + return (struct sock *)hvsk; +} + #endif /* __AF_HVSOCK_H__ */ diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h index 955a004..d942996 100644 --- a/include/uapi/linux/hyperv.h +++ b/include/uapi/linux/hyperv.h @@ -397,7 +397,7 @@ struct hv_kvp_ip_msg { struct hv_kvp_ipaddr_value kvp_ip_val; } __attribute__((packed)); -/* This is the address fromat of Hyper-V Sockets. +/* This is the address format of Hyper-V Sockets. * Note: here we just borrow the kernel's built-in type uuid_le. When * an application calls bind() or connect(), the 2 members of struct * sockaddr_hv must be of GUID. diff --git a/net/hv_sock/af_hvsock.c b/net/hv_sock/af_hvsock.c index cf7c3bd..f339f38 100644 --- a/net/hv_sock/af_hvsock.c +++ b/net/hv_sock/af_hvsock.c @@ -2,7 +2,9 @@ * Hyper-V Sockets -- a socket-based communication channel between the * Hyper-V host and the virtual machines running on it. * - * Copyright(c) 2016, Microsoft Corporation. All rights reserved. + * Copyright (c) 2016 Microsoft Corporation. + * + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -17,6 +19,10 @@ * products derived from this software without specific prior written * permission. * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -1246,8 +1252,8 @@ static int hvsock_recvmsg_wait(struct sock *sk, struct msghdr *msg, ret = hvsock_recv_data(channel, hvsk, &payload_len); - if (ret != 0 || payload_len > - sizeof(hvsk->recv->buf)) { + if (ret != 0 || + payload_len > sizeof(hvsk->recv->buf)) { ret = -EIO; hvsock_put_recv_buf(hvsk); goto out_wait; @@ -1473,10 +1479,8 @@ static int __init hvsock_init(void) int ret; /* Hyper-V Sockets requires at least VMBus 4.0 */ - if ((vmbus_proto_version >> 16) < 4) { - pr_err("failed to load: VMBus 4 or later is required\n"); + if ((vmbus_proto_version >> 16) < 4) return -ENODEV; - } ret = vmbus_driver_register(&hvsock_drv); if (ret) {