Skip to content

Commit 8aeab13

Browse files
committed
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio updates from Michael Tsirkin: - 9k mtu perf improvements - vdpa feature provisioning - virtio blk SECURE ERASE support - fixes and cleanups all over the place * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: virtio_pci: don't try to use intxif pin is zero vDPA: conditionally read MTU and MAC in dev cfg space vDPA: fix spars cast warning in vdpa_dev_net_mq_config_fill vDPA: check virtio device features to detect MQ vDPA: check VIRTIO_NET_F_RSS for max_virtqueue_paris's presence vDPA: only report driver features if FEATURES_OK is set vDPA: allow userspace to query features of a vDPA device virtio_blk: add SECURE ERASE command support vp_vdpa: support feature provisioning vdpa_sim_net: support feature provisioning vdpa: device feature provisioning virtio-net: use mtu size as buffer length for big packets virtio-net: introduce and use helper function for guest gso support checks virtio: drop vp_legacy_set_queue_size virtio_ring: make vring_alloc_queue_packed prettier virtio_ring: split: Operators use unified style vhost: add __init/__exit annotations to module init/exit funcs
2 parents 0e0073e + 71491c5 commit 8aeab13

File tree

15 files changed

+253
-65
lines changed

15 files changed

+253
-65
lines changed

drivers/block/virtio_blk.c

Lines changed: 92 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr)
130130
return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC);
131131
}
132132

133-
static int virtblk_setup_discard_write_zeroes(struct request *req, bool unmap)
133+
static int virtblk_setup_discard_write_zeroes_erase(struct request *req, bool unmap)
134134
{
135135
unsigned short segments = blk_rq_nr_discard_segments(req);
136136
unsigned short n = 0;
@@ -240,6 +240,9 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev,
240240
type = VIRTIO_BLK_T_WRITE_ZEROES;
241241
unmap = !(req->cmd_flags & REQ_NOUNMAP);
242242
break;
243+
case REQ_OP_SECURE_ERASE:
244+
type = VIRTIO_BLK_T_SECURE_ERASE;
245+
break;
243246
case REQ_OP_DRV_IN:
244247
type = VIRTIO_BLK_T_GET_ID;
245248
break;
@@ -251,8 +254,9 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev,
251254
vbr->out_hdr.type = cpu_to_virtio32(vdev, type);
252255
vbr->out_hdr.ioprio = cpu_to_virtio32(vdev, req_get_ioprio(req));
253256

254-
if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES) {
255-
if (virtblk_setup_discard_write_zeroes(req, unmap))
257+
if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES ||
258+
type == VIRTIO_BLK_T_SECURE_ERASE) {
259+
if (virtblk_setup_discard_write_zeroes_erase(req, unmap))
256260
return BLK_STS_RESOURCE;
257261
}
258262

@@ -886,6 +890,8 @@ static int virtblk_probe(struct virtio_device *vdev)
886890
int err, index;
887891

888892
u32 v, blk_size, max_size, sg_elems, opt_io_size;
893+
u32 max_discard_segs = 0;
894+
u32 discard_granularity = 0;
889895
u16 min_io_size;
890896
u8 physical_block_exp, alignment_offset;
891897
unsigned int queue_depth;
@@ -1043,27 +1049,14 @@ static int virtblk_probe(struct virtio_device *vdev)
10431049

10441050
if (virtio_has_feature(vdev, VIRTIO_BLK_F_DISCARD)) {
10451051
virtio_cread(vdev, struct virtio_blk_config,
1046-
discard_sector_alignment, &v);
1047-
if (v)
1048-
q->limits.discard_granularity = v << SECTOR_SHIFT;
1049-
else
1050-
q->limits.discard_granularity = blk_size;
1052+
discard_sector_alignment, &discard_granularity);
10511053

10521054
virtio_cread(vdev, struct virtio_blk_config,
10531055
max_discard_sectors, &v);
10541056
blk_queue_max_discard_sectors(q, v ? v : UINT_MAX);
10551057

10561058
virtio_cread(vdev, struct virtio_blk_config, max_discard_seg,
1057-
&v);
1058-
1059-
/*
1060-
* max_discard_seg == 0 is out of spec but we always
1061-
* handled it.
1062-
*/
1063-
if (!v)
1064-
v = sg_elems;
1065-
blk_queue_max_discard_segments(q,
1066-
min(v, MAX_DISCARD_SEGMENTS));
1059+
&max_discard_segs);
10671060
}
10681061

10691062
if (virtio_has_feature(vdev, VIRTIO_BLK_F_WRITE_ZEROES)) {
@@ -1072,6 +1065,85 @@ static int virtblk_probe(struct virtio_device *vdev)
10721065
blk_queue_max_write_zeroes_sectors(q, v ? v : UINT_MAX);
10731066
}
10741067

1068+
/* The discard and secure erase limits are combined since the Linux
1069+
* block layer uses the same limit for both commands.
1070+
*
1071+
* If both VIRTIO_BLK_F_SECURE_ERASE and VIRTIO_BLK_F_DISCARD features
1072+
* are negotiated, we will use the minimum between the limits.
1073+
*
1074+
* discard sector alignment is set to the minimum between discard_sector_alignment
1075+
* and secure_erase_sector_alignment.
1076+
*
1077+
* max discard sectors is set to the minimum between max_discard_seg and
1078+
* max_secure_erase_seg.
1079+
*/
1080+
if (virtio_has_feature(vdev, VIRTIO_BLK_F_SECURE_ERASE)) {
1081+
1082+
virtio_cread(vdev, struct virtio_blk_config,
1083+
secure_erase_sector_alignment, &v);
1084+
1085+
/* secure_erase_sector_alignment should not be zero, the device should set a
1086+
* valid number of sectors.
1087+
*/
1088+
if (!v) {
1089+
dev_err(&vdev->dev,
1090+
"virtio_blk: secure_erase_sector_alignment can't be 0\n");
1091+
err = -EINVAL;
1092+
goto out_cleanup_disk;
1093+
}
1094+
1095+
discard_granularity = min_not_zero(discard_granularity, v);
1096+
1097+
virtio_cread(vdev, struct virtio_blk_config,
1098+
max_secure_erase_sectors, &v);
1099+
1100+
/* max_secure_erase_sectors should not be zero, the device should set a
1101+
* valid number of sectors.
1102+
*/
1103+
if (!v) {
1104+
dev_err(&vdev->dev,
1105+
"virtio_blk: max_secure_erase_sectors can't be 0\n");
1106+
err = -EINVAL;
1107+
goto out_cleanup_disk;
1108+
}
1109+
1110+
blk_queue_max_secure_erase_sectors(q, v);
1111+
1112+
virtio_cread(vdev, struct virtio_blk_config,
1113+
max_secure_erase_seg, &v);
1114+
1115+
/* max_secure_erase_seg should not be zero, the device should set a
1116+
* valid number of segments
1117+
*/
1118+
if (!v) {
1119+
dev_err(&vdev->dev,
1120+
"virtio_blk: max_secure_erase_seg can't be 0\n");
1121+
err = -EINVAL;
1122+
goto out_cleanup_disk;
1123+
}
1124+
1125+
max_discard_segs = min_not_zero(max_discard_segs, v);
1126+
}
1127+
1128+
if (virtio_has_feature(vdev, VIRTIO_BLK_F_DISCARD) ||
1129+
virtio_has_feature(vdev, VIRTIO_BLK_F_SECURE_ERASE)) {
1130+
/* max_discard_seg and discard_granularity will be 0 only
1131+
* if max_discard_seg and discard_sector_alignment fields in the virtio
1132+
* config are 0 and VIRTIO_BLK_F_SECURE_ERASE feature is not negotiated.
1133+
* In this case, we use default values.
1134+
*/
1135+
if (!max_discard_segs)
1136+
max_discard_segs = sg_elems;
1137+
1138+
blk_queue_max_discard_segments(q,
1139+
min(max_discard_segs, MAX_DISCARD_SEGMENTS));
1140+
1141+
if (discard_granularity)
1142+
q->limits.discard_granularity = discard_granularity << SECTOR_SHIFT;
1143+
else
1144+
q->limits.discard_granularity = blk_size;
1145+
}
1146+
10751147
virtblk_update_capacity(vblk, false);
10761148
virtio_device_ready(vdev);
10771149

@@ -1167,13 +1239,15 @@ static unsigned int features_legacy[] = {
11671239
VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
11681240
VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
11691241
VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
1242+
VIRTIO_BLK_F_SECURE_ERASE,
11701243
}
11711244
;
11721245
static unsigned int features[] = {
11731246
VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
11741247
VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
11751248
VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
11761249
VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
1250+
VIRTIO_BLK_F_SECURE_ERASE,
11771251
};
11781252

11791253
static struct virtio_driver virtio_blk = {

drivers/net/virtio_net.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ struct virtnet_info {
225225
/* I like... big packets and I cannot lie! */
226226
bool big_packets;
227227

228+
/* number of sg entries allocated for big packets */
229+
unsigned int big_packets_num_skbfrags;
230+
228231
/* Host will merge rx buffers for big packets (shake it! shake it!) */
229232
bool mergeable_rx_bufs;
230233

@@ -1331,10 +1334,10 @@ static int add_recvbuf_big(struct virtnet_info *vi, struct receive_queue *rq,
13311334
char *p;
13321335
int i, err, offset;
13331336

1334-
sg_init_table(rq->sg, MAX_SKB_FRAGS + 2);
1337+
sg_init_table(rq->sg, vi->big_packets_num_skbfrags + 2);
13351338

1336-
/* page in rq->sg[MAX_SKB_FRAGS + 1] is list tail */
1337-
for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
1339+
/* page in rq->sg[vi->big_packets_num_skbfrags + 1] is list tail */
1340+
for (i = vi->big_packets_num_skbfrags + 1; i > 1; --i) {
13381341
first = get_a_page(rq, gfp);
13391342
if (!first) {
13401343
if (list)
@@ -1365,7 +1368,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, struct receive_queue *rq,
13651368

13661369
/* chain first in list head */
13671370
first->private = (unsigned long)list;
1368-
err = virtqueue_add_inbuf(rq->vq, rq->sg, MAX_SKB_FRAGS + 2,
1371+
err = virtqueue_add_inbuf(rq->vq, rq->sg, vi->big_packets_num_skbfrags + 2,
13691372
first, gfp);
13701373
if (err < 0)
13711374
give_pages(rq, first);
@@ -3682,13 +3685,35 @@ static int virtnet_validate(struct virtio_device *vdev)
36823685
return 0;
36833686
}
36843687

3688+
static bool virtnet_check_guest_gso(const struct virtnet_info *vi)
3689+
{
3690+
return virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) ||
3691+
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
3692+
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
3693+
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO);
3694+
}
3695+
3696+
static void virtnet_set_big_packets(struct virtnet_info *vi, const int mtu)
3697+
{
3698+
bool guest_gso = virtnet_check_guest_gso(vi);
3699+
3700+
/* If device can receive ANY guest GSO packets, regardless of mtu,
3701+
* allocate packets of maximum size, otherwise limit it to only
3702+
* mtu size worth only.
3703+
*/
3704+
if (mtu > ETH_DATA_LEN || guest_gso) {
3705+
vi->big_packets = true;
3706+
vi->big_packets_num_skbfrags = guest_gso ? MAX_SKB_FRAGS : DIV_ROUND_UP(mtu, PAGE_SIZE);
3707+
}
3708+
}
3709+
36853710
static int virtnet_probe(struct virtio_device *vdev)
36863711
{
36873712
int i, err = -ENOMEM;
36883713
struct net_device *dev;
36893714
struct virtnet_info *vi;
36903715
u16 max_queue_pairs;
3691-
int mtu;
3716+
int mtu = 0;
36923717

36933718
/* Find if host supports multiqueue/rss virtio_net device */
36943719
max_queue_pairs = 1;
@@ -3776,13 +3801,6 @@ static int virtnet_probe(struct virtio_device *vdev)
37763801
INIT_WORK(&vi->config_work, virtnet_config_changed_work);
37773802
spin_lock_init(&vi->refill_lock);
37783803

3779-
/* If we can receive ANY GSO packets, we must allocate large ones. */
3780-
if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
3781-
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
3782-
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
3783-
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
3784-
vi->big_packets = true;
3785-
37863804
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
37873805
vi->mergeable_rx_bufs = true;
37883806

@@ -3848,12 +3866,10 @@ static int virtnet_probe(struct virtio_device *vdev)
38483866

38493867
dev->mtu = mtu;
38503868
dev->max_mtu = mtu;
3851-
3852-
/* TODO: size buffers correctly in this case. */
3853-
if (dev->mtu > ETH_DATA_LEN)
3854-
vi->big_packets = true;
38553869
}
38563870

3871+
virtnet_set_big_packets(vi, mtu);
3872+
38573873
if (vi->any_header_sg)
38583874
dev->needed_headroom = vi->hdr_len;
38593875

drivers/vdpa/vdpa.c

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,11 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i
600600
}
601601
config.mask |= BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);
602602
}
603+
if (nl_attrs[VDPA_ATTR_DEV_FEATURES]) {
604+
config.device_features =
605+
nla_get_u64(nl_attrs[VDPA_ATTR_DEV_FEATURES]);
606+
config.mask |= BIT_ULL(VDPA_ATTR_DEV_FEATURES);
607+
}
603608

604609
/* Skip checking capability if user didn't prefer to configure any
605610
* device networking attributes. It is likely that user might have used
@@ -799,51 +804,76 @@ static int vdpa_nl_cmd_dev_get_dumpit(struct sk_buff *msg, struct netlink_callba
799804
return msg->len;
800805
}
801806

802-
static int vdpa_dev_net_mq_config_fill(struct vdpa_device *vdev,
803-
struct sk_buff *msg, u64 features,
807+
static int vdpa_dev_net_mq_config_fill(struct sk_buff *msg, u64 features,
804808
const struct virtio_net_config *config)
805809
{
806810
u16 val_u16;
807811

808-
if ((features & BIT_ULL(VIRTIO_NET_F_MQ)) == 0)
812+
if ((features & BIT_ULL(VIRTIO_NET_F_MQ)) == 0 &&
813+
(features & BIT_ULL(VIRTIO_NET_F_RSS)) == 0)
809814
return 0;
810815

811-
val_u16 = le16_to_cpu(config->max_virtqueue_pairs);
816+
val_u16 = __virtio16_to_cpu(true, config->max_virtqueue_pairs);
817+
812818
return nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MAX_VQP, val_u16);
813819
}
814820

821+
static int vdpa_dev_net_mtu_config_fill(struct sk_buff *msg, u64 features,
822+
const struct virtio_net_config *config)
823+
{
824+
u16 val_u16;
825+
826+
if ((features & BIT_ULL(VIRTIO_NET_F_MTU)) == 0)
827+
return 0;
828+
829+
val_u16 = __virtio16_to_cpu(true, config->mtu);
830+
831+
return nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MTU, val_u16);
832+
}
833+
834+
static int vdpa_dev_net_mac_config_fill(struct sk_buff *msg, u64 features,
835+
const struct virtio_net_config *config)
836+
{
837+
if ((features & BIT_ULL(VIRTIO_NET_F_MAC)) == 0)
838+
return 0;
839+
840+
return nla_put(msg, VDPA_ATTR_DEV_NET_CFG_MACADDR,
841+
sizeof(config->mac), config->mac);
842+
}
843+
815844
static int vdpa_dev_net_config_fill(struct vdpa_device *vdev, struct sk_buff *msg)
816845
{
817846
struct virtio_net_config config = {};
818-
u64 features;
847+
u64 features_device;
819848
u16 val_u16;
820849

821-
vdpa_get_config_unlocked(vdev, 0, &config, sizeof(config));
822-
823-
if (nla_put(msg, VDPA_ATTR_DEV_NET_CFG_MACADDR, sizeof(config.mac),
824-
config.mac))
825-
return -EMSGSIZE;
850+
vdev->config->get_config(vdev, 0, &config, sizeof(config));
826851

827852
val_u16 = __virtio16_to_cpu(true, config.status);
828853
if (nla_put_u16(msg, VDPA_ATTR_DEV_NET_STATUS, val_u16))
829854
return -EMSGSIZE;
830855

831-
val_u16 = __virtio16_to_cpu(true, config.mtu);
832-
if (nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MTU, val_u16))
833-
return -EMSGSIZE;
856+
features_device = vdev->config->get_device_features(vdev);
834857

835-
features = vdev->config->get_driver_features(vdev);
836-
if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_NEGOTIATED_FEATURES, features,
858+
if (nla_put_u64_64bit(msg, VDPA_ATTR_VDPA_DEV_SUPPORTED_FEATURES, features_device,
837859
VDPA_ATTR_PAD))
838860
return -EMSGSIZE;
839861

840-
return vdpa_dev_net_mq_config_fill(vdev, msg, features, &config);
862+
if (vdpa_dev_net_mtu_config_fill(msg, features_device, &config))
863+
return -EMSGSIZE;
864+
865+
if (vdpa_dev_net_mac_config_fill(msg, features_device, &config))
866+
return -EMSGSIZE;
867+
868+
return vdpa_dev_net_mq_config_fill(msg, features_device, &config);
841869
}
842870

843871
static int
844872
vdpa_dev_config_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, u32 seq,
845873
int flags, struct netlink_ext_ack *extack)
846874
{
875+
u64 features_driver;
876+
u8 status = 0;
847877
u32 device_id;
848878
void *hdr;
849879
int err;
@@ -867,6 +897,17 @@ vdpa_dev_config_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid,
867897
goto msg_err;
868898
}
869899

900+
/* only read driver features after the feature negotiation is done */
901+
status = vdev->config->get_status(vdev);
902+
if (status & VIRTIO_CONFIG_S_FEATURES_OK) {
903+
features_driver = vdev->config->get_driver_features(vdev);
904+
if (nla_put_u64_64bit(msg, VDPA_ATTR_DEV_NEGOTIATED_FEATURES, features_driver,
905+
VDPA_ATTR_PAD)) {
906+
err = -EMSGSIZE;
907+
goto msg_err;
908+
}
909+
}
910+
870911
switch (device_id) {
871912
case VIRTIO_ID_NET:
872913
err = vdpa_dev_net_config_fill(vdev, msg);

0 commit comments

Comments
 (0)