Skip to content

Commit b9f2b0f

Browse files
stefano-garzarelladavem330
authored andcommitted
vsock: handle buffer_size sockopts in the core
virtio_transport and vmci_transport handle the buffer_size sockopts in a very similar way. In order to support multiple transports, this patch moves this handling in the core to allow the user to change the options also if the socket is not yet assigned to any transport. This patch also adds the '.notify_buffer_size' callback in the 'struct virtio_transport' in order to inform the transport, when the buffer_size is changed by the user. It is also useful to limit the 'buffer_size' requested (e.g. virtio transports). Acked-by: Dexuan Cui <[email protected]> Reviewed-by: Stefan Hajnoczi <[email protected]> Reviewed-by: Jorgen Hansen <[email protected]> Signed-off-by: Stefano Garzarella <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent daabfbc commit b9f2b0f

File tree

9 files changed

+65
-227
lines changed

9 files changed

+65
-227
lines changed

drivers/vhost/vsock.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,13 +418,8 @@ static struct virtio_transport vhost_transport = {
418418
.notify_send_pre_block = virtio_transport_notify_send_pre_block,
419419
.notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue,
420420
.notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
421+
.notify_buffer_size = virtio_transport_notify_buffer_size,
421422

422-
.set_buffer_size = virtio_transport_set_buffer_size,
423-
.set_min_buffer_size = virtio_transport_set_min_buffer_size,
424-
.set_max_buffer_size = virtio_transport_set_max_buffer_size,
425-
.get_buffer_size = virtio_transport_get_buffer_size,
426-
.get_min_buffer_size = virtio_transport_get_min_buffer_size,
427-
.get_max_buffer_size = virtio_transport_get_max_buffer_size,
428423
},
429424

430425
.send_pkt = vhost_transport_send_pkt,

include/linux/virtio_vsock.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
#include <net/sock.h>
88
#include <net/af_vsock.h>
99

10-
#define VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE 128
11-
#define VIRTIO_VSOCK_DEFAULT_BUF_SIZE (1024 * 256)
12-
#define VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE (1024 * 256)
1310
#define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE (1024 * 4)
1411
#define VIRTIO_VSOCK_MAX_BUF_SIZE 0xFFFFFFFFUL
1512
#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
@@ -25,11 +22,6 @@ enum {
2522
struct virtio_vsock_sock {
2623
struct vsock_sock *vsk;
2724

28-
/* Protected by lock_sock(sk_vsock(trans->vsk)) */
29-
u32 buf_size;
30-
u32 buf_size_min;
31-
u32 buf_size_max;
32-
3325
spinlock_t tx_lock;
3426
spinlock_t rx_lock;
3527

@@ -92,12 +84,6 @@ s64 virtio_transport_stream_has_space(struct vsock_sock *vsk);
9284

9385
int virtio_transport_do_socket_init(struct vsock_sock *vsk,
9486
struct vsock_sock *psk);
95-
u64 virtio_transport_get_buffer_size(struct vsock_sock *vsk);
96-
u64 virtio_transport_get_min_buffer_size(struct vsock_sock *vsk);
97-
u64 virtio_transport_get_max_buffer_size(struct vsock_sock *vsk);
98-
void virtio_transport_set_buffer_size(struct vsock_sock *vsk, u64 val);
99-
void virtio_transport_set_min_buffer_size(struct vsock_sock *vsk, u64 val);
100-
void virtio_transport_set_max_buffer_size(struct vsock_sock *vs, u64 val);
10187
int
10288
virtio_transport_notify_poll_in(struct vsock_sock *vsk,
10389
size_t target,
@@ -124,6 +110,7 @@ int virtio_transport_notify_send_pre_enqueue(struct vsock_sock *vsk,
124110
struct vsock_transport_send_notify_data *data);
125111
int virtio_transport_notify_send_post_enqueue(struct vsock_sock *vsk,
126112
ssize_t written, struct vsock_transport_send_notify_data *data);
113+
void virtio_transport_notify_buffer_size(struct vsock_sock *vsk, u64 *val);
127114

128115
u64 virtio_transport_stream_rcvhiwat(struct vsock_sock *vsk);
129116
bool virtio_transport_stream_is_active(struct vsock_sock *vsk);

include/net/af_vsock.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ struct vsock_sock {
6565
bool sent_request;
6666
bool ignore_connecting_rst;
6767

68+
/* Protected by lock_sock(sk) */
69+
u64 buffer_size;
70+
u64 buffer_min_size;
71+
u64 buffer_max_size;
72+
6873
/* Private to transport. */
6974
void *trans;
7075
};
@@ -140,18 +145,12 @@ struct vsock_transport {
140145
struct vsock_transport_send_notify_data *);
141146
int (*notify_send_post_enqueue)(struct vsock_sock *, ssize_t,
142147
struct vsock_transport_send_notify_data *);
148+
/* sk_lock held by the caller */
149+
void (*notify_buffer_size)(struct vsock_sock *, u64 *);
143150

144151
/* Shutdown. */
145152
int (*shutdown)(struct vsock_sock *, int);
146153

147-
/* Buffer sizes. */
148-
void (*set_buffer_size)(struct vsock_sock *, u64);
149-
void (*set_min_buffer_size)(struct vsock_sock *, u64);
150-
void (*set_max_buffer_size)(struct vsock_sock *, u64);
151-
u64 (*get_buffer_size)(struct vsock_sock *);
152-
u64 (*get_min_buffer_size)(struct vsock_sock *);
153-
u64 (*get_max_buffer_size)(struct vsock_sock *);
154-
155154
/* Addressing. */
156155
u32 (*get_local_cid)(void);
157156
};

net/vmw_vsock/af_vsock.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ static struct proto vsock_proto = {
126126
*/
127127
#define VSOCK_DEFAULT_CONNECT_TIMEOUT (2 * HZ)
128128

129+
#define VSOCK_DEFAULT_BUFFER_SIZE (1024 * 256)
130+
#define VSOCK_DEFAULT_BUFFER_MAX_SIZE (1024 * 256)
131+
#define VSOCK_DEFAULT_BUFFER_MIN_SIZE 128
132+
129133
static const struct vsock_transport *transport_single;
130134
static DEFINE_MUTEX(vsock_register_mutex);
131135

@@ -613,10 +617,16 @@ struct sock *__vsock_create(struct net *net,
613617
vsk->trusted = psk->trusted;
614618
vsk->owner = get_cred(psk->owner);
615619
vsk->connect_timeout = psk->connect_timeout;
620+
vsk->buffer_size = psk->buffer_size;
621+
vsk->buffer_min_size = psk->buffer_min_size;
622+
vsk->buffer_max_size = psk->buffer_max_size;
616623
} else {
617624
vsk->trusted = capable(CAP_NET_ADMIN);
618625
vsk->owner = get_current_cred();
619626
vsk->connect_timeout = VSOCK_DEFAULT_CONNECT_TIMEOUT;
627+
vsk->buffer_size = VSOCK_DEFAULT_BUFFER_SIZE;
628+
vsk->buffer_min_size = VSOCK_DEFAULT_BUFFER_MIN_SIZE;
629+
vsk->buffer_max_size = VSOCK_DEFAULT_BUFFER_MAX_SIZE;
620630
}
621631

622632
if (vsk->transport->init(vsk, psk) < 0) {
@@ -1366,6 +1376,23 @@ static int vsock_listen(struct socket *sock, int backlog)
13661376
return err;
13671377
}
13681378

1379+
static void vsock_update_buffer_size(struct vsock_sock *vsk,
1380+
const struct vsock_transport *transport,
1381+
u64 val)
1382+
{
1383+
if (val > vsk->buffer_max_size)
1384+
val = vsk->buffer_max_size;
1385+
1386+
if (val < vsk->buffer_min_size)
1387+
val = vsk->buffer_min_size;
1388+
1389+
if (val != vsk->buffer_size &&
1390+
transport && transport->notify_buffer_size)
1391+
transport->notify_buffer_size(vsk, &val);
1392+
1393+
vsk->buffer_size = val;
1394+
}
1395+
13691396
static int vsock_stream_setsockopt(struct socket *sock,
13701397
int level,
13711398
int optname,
@@ -1403,17 +1430,19 @@ static int vsock_stream_setsockopt(struct socket *sock,
14031430
switch (optname) {
14041431
case SO_VM_SOCKETS_BUFFER_SIZE:
14051432
COPY_IN(val);
1406-
transport->set_buffer_size(vsk, val);
1433+
vsock_update_buffer_size(vsk, transport, val);
14071434
break;
14081435

14091436
case SO_VM_SOCKETS_BUFFER_MAX_SIZE:
14101437
COPY_IN(val);
1411-
transport->set_max_buffer_size(vsk, val);
1438+
vsk->buffer_max_size = val;
1439+
vsock_update_buffer_size(vsk, transport, vsk->buffer_size);
14121440
break;
14131441

14141442
case SO_VM_SOCKETS_BUFFER_MIN_SIZE:
14151443
COPY_IN(val);
1416-
transport->set_min_buffer_size(vsk, val);
1444+
vsk->buffer_min_size = val;
1445+
vsock_update_buffer_size(vsk, transport, vsk->buffer_size);
14171446
break;
14181447

14191448
case SO_VM_SOCKETS_CONNECT_TIMEOUT: {
@@ -1454,7 +1483,6 @@ static int vsock_stream_getsockopt(struct socket *sock,
14541483
int len;
14551484
struct sock *sk;
14561485
struct vsock_sock *vsk;
1457-
const struct vsock_transport *transport;
14581486
u64 val;
14591487

14601488
if (level != AF_VSOCK)
@@ -1478,21 +1506,20 @@ static int vsock_stream_getsockopt(struct socket *sock,
14781506
err = 0;
14791507
sk = sock->sk;
14801508
vsk = vsock_sk(sk);
1481-
transport = vsk->transport;
14821509

14831510
switch (optname) {
14841511
case SO_VM_SOCKETS_BUFFER_SIZE:
1485-
val = transport->get_buffer_size(vsk);
1512+
val = vsk->buffer_size;
14861513
COPY_OUT(val);
14871514
break;
14881515

14891516
case SO_VM_SOCKETS_BUFFER_MAX_SIZE:
1490-
val = transport->get_max_buffer_size(vsk);
1517+
val = vsk->buffer_max_size;
14911518
COPY_OUT(val);
14921519
break;
14931520

14941521
case SO_VM_SOCKETS_BUFFER_MIN_SIZE:
1495-
val = transport->get_min_buffer_size(vsk);
1522+
val = vsk->buffer_min_size;
14961523
COPY_OUT(val);
14971524
break;
14981525

net/vmw_vsock/hyperv_transport.c

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -845,36 +845,6 @@ int hvs_notify_send_post_enqueue(struct vsock_sock *vsk, ssize_t written,
845845
return 0;
846846
}
847847

848-
static void hvs_set_buffer_size(struct vsock_sock *vsk, u64 val)
849-
{
850-
/* Ignored. */
851-
}
852-
853-
static void hvs_set_min_buffer_size(struct vsock_sock *vsk, u64 val)
854-
{
855-
/* Ignored. */
856-
}
857-
858-
static void hvs_set_max_buffer_size(struct vsock_sock *vsk, u64 val)
859-
{
860-
/* Ignored. */
861-
}
862-
863-
static u64 hvs_get_buffer_size(struct vsock_sock *vsk)
864-
{
865-
return -ENOPROTOOPT;
866-
}
867-
868-
static u64 hvs_get_min_buffer_size(struct vsock_sock *vsk)
869-
{
870-
return -ENOPROTOOPT;
871-
}
872-
873-
static u64 hvs_get_max_buffer_size(struct vsock_sock *vsk)
874-
{
875-
return -ENOPROTOOPT;
876-
}
877-
878848
static struct vsock_transport hvs_transport = {
879849
.get_local_cid = hvs_get_local_cid,
880850

@@ -908,12 +878,6 @@ static struct vsock_transport hvs_transport = {
908878
.notify_send_pre_enqueue = hvs_notify_send_pre_enqueue,
909879
.notify_send_post_enqueue = hvs_notify_send_post_enqueue,
910880

911-
.set_buffer_size = hvs_set_buffer_size,
912-
.set_min_buffer_size = hvs_set_min_buffer_size,
913-
.set_max_buffer_size = hvs_set_max_buffer_size,
914-
.get_buffer_size = hvs_get_buffer_size,
915-
.get_min_buffer_size = hvs_get_min_buffer_size,
916-
.get_max_buffer_size = hvs_get_max_buffer_size,
917881
};
918882

919883
static int hvs_probe(struct hv_device *hdev,

net/vmw_vsock/virtio_transport.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -494,13 +494,7 @@ static struct virtio_transport virtio_transport = {
494494
.notify_send_pre_block = virtio_transport_notify_send_pre_block,
495495
.notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue,
496496
.notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
497-
498-
.set_buffer_size = virtio_transport_set_buffer_size,
499-
.set_min_buffer_size = virtio_transport_set_min_buffer_size,
500-
.set_max_buffer_size = virtio_transport_set_max_buffer_size,
501-
.get_buffer_size = virtio_transport_get_buffer_size,
502-
.get_min_buffer_size = virtio_transport_get_min_buffer_size,
503-
.get_max_buffer_size = virtio_transport_get_max_buffer_size,
497+
.notify_buffer_size = virtio_transport_notify_buffer_size,
504498
},
505499

506500
.send_pkt = virtio_transport_send_pkt,

net/vmw_vsock/virtio_transport_common.c

Lines changed: 11 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -456,17 +456,13 @@ int virtio_transport_do_socket_init(struct vsock_sock *vsk,
456456
if (psk) {
457457
struct virtio_vsock_sock *ptrans = psk->trans;
458458

459-
vvs->buf_size = ptrans->buf_size;
460-
vvs->buf_size_min = ptrans->buf_size_min;
461-
vvs->buf_size_max = ptrans->buf_size_max;
462459
vvs->peer_buf_alloc = ptrans->peer_buf_alloc;
463-
} else {
464-
vvs->buf_size = VIRTIO_VSOCK_DEFAULT_BUF_SIZE;
465-
vvs->buf_size_min = VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE;
466-
vvs->buf_size_max = VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE;
467460
}
468461

469-
vvs->buf_alloc = vvs->buf_size;
462+
if (vsk->buffer_size > VIRTIO_VSOCK_MAX_BUF_SIZE)
463+
vsk->buffer_size = VIRTIO_VSOCK_MAX_BUF_SIZE;
464+
465+
vvs->buf_alloc = vsk->buffer_size;
470466

471467
spin_lock_init(&vvs->rx_lock);
472468
spin_lock_init(&vvs->tx_lock);
@@ -476,71 +472,20 @@ int virtio_transport_do_socket_init(struct vsock_sock *vsk,
476472
}
477473
EXPORT_SYMBOL_GPL(virtio_transport_do_socket_init);
478474

479-
u64 virtio_transport_get_buffer_size(struct vsock_sock *vsk)
480-
{
481-
struct virtio_vsock_sock *vvs = vsk->trans;
482-
483-
return vvs->buf_size;
484-
}
485-
EXPORT_SYMBOL_GPL(virtio_transport_get_buffer_size);
486-
487-
u64 virtio_transport_get_min_buffer_size(struct vsock_sock *vsk)
475+
/* sk_lock held by the caller */
476+
void virtio_transport_notify_buffer_size(struct vsock_sock *vsk, u64 *val)
488477
{
489478
struct virtio_vsock_sock *vvs = vsk->trans;
490479

491-
return vvs->buf_size_min;
492-
}
493-
EXPORT_SYMBOL_GPL(virtio_transport_get_min_buffer_size);
494-
495-
u64 virtio_transport_get_max_buffer_size(struct vsock_sock *vsk)
496-
{
497-
struct virtio_vsock_sock *vvs = vsk->trans;
498-
499-
return vvs->buf_size_max;
500-
}
501-
EXPORT_SYMBOL_GPL(virtio_transport_get_max_buffer_size);
502-
503-
void virtio_transport_set_buffer_size(struct vsock_sock *vsk, u64 val)
504-
{
505-
struct virtio_vsock_sock *vvs = vsk->trans;
480+
if (*val > VIRTIO_VSOCK_MAX_BUF_SIZE)
481+
*val = VIRTIO_VSOCK_MAX_BUF_SIZE;
506482

507-
if (val > VIRTIO_VSOCK_MAX_BUF_SIZE)
508-
val = VIRTIO_VSOCK_MAX_BUF_SIZE;
509-
if (val < vvs->buf_size_min)
510-
vvs->buf_size_min = val;
511-
if (val > vvs->buf_size_max)
512-
vvs->buf_size_max = val;
513-
vvs->buf_size = val;
514-
vvs->buf_alloc = val;
483+
vvs->buf_alloc = *val;
515484

516485
virtio_transport_send_credit_update(vsk, VIRTIO_VSOCK_TYPE_STREAM,
517486
NULL);
518487
}
519-
EXPORT_SYMBOL_GPL(virtio_transport_set_buffer_size);
520-
521-
void virtio_transport_set_min_buffer_size(struct vsock_sock *vsk, u64 val)
522-
{
523-
struct virtio_vsock_sock *vvs = vsk->trans;
524-
525-
if (val > VIRTIO_VSOCK_MAX_BUF_SIZE)
526-
val = VIRTIO_VSOCK_MAX_BUF_SIZE;
527-
if (val > vvs->buf_size)
528-
vvs->buf_size = val;
529-
vvs->buf_size_min = val;
530-
}
531-
EXPORT_SYMBOL_GPL(virtio_transport_set_min_buffer_size);
532-
533-
void virtio_transport_set_max_buffer_size(struct vsock_sock *vsk, u64 val)
534-
{
535-
struct virtio_vsock_sock *vvs = vsk->trans;
536-
537-
if (val > VIRTIO_VSOCK_MAX_BUF_SIZE)
538-
val = VIRTIO_VSOCK_MAX_BUF_SIZE;
539-
if (val < vvs->buf_size)
540-
vvs->buf_size = val;
541-
vvs->buf_size_max = val;
542-
}
543-
EXPORT_SYMBOL_GPL(virtio_transport_set_max_buffer_size);
488+
EXPORT_SYMBOL_GPL(virtio_transport_notify_buffer_size);
544489

545490
int
546491
virtio_transport_notify_poll_in(struct vsock_sock *vsk,
@@ -632,9 +577,7 @@ EXPORT_SYMBOL_GPL(virtio_transport_notify_send_post_enqueue);
632577

633578
u64 virtio_transport_stream_rcvhiwat(struct vsock_sock *vsk)
634579
{
635-
struct virtio_vsock_sock *vvs = vsk->trans;
636-
637-
return vvs->buf_size;
580+
return vsk->buffer_size;
638581
}
639582
EXPORT_SYMBOL_GPL(virtio_transport_stream_rcvhiwat);
640583

0 commit comments

Comments
 (0)