Skip to content

Commit 0686082

Browse files
YongjiXiemstsirkin
authored andcommitted
vdpa: Add reset callback in vdpa_config_ops
This adds a new callback to support device specific reset behavior. The vdpa bus driver will call the reset function instead of setting status to zero during resetting. Signed-off-by: Xie Yongji <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 86e17a5 commit 0686082

File tree

6 files changed

+89
-36
lines changed

6 files changed

+89
-36
lines changed

drivers/vdpa/ifcvf/ifcvf_main.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,6 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
222222
if (status_old == status)
223223
return;
224224

225-
if ((status_old & VIRTIO_CONFIG_S_DRIVER_OK) &&
226-
!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
227-
ifcvf_stop_datapath(adapter);
228-
ifcvf_free_irq(adapter, vf->nr_vring);
229-
}
230-
231-
if (status == 0) {
232-
ifcvf_reset_vring(adapter);
233-
return;
234-
}
235-
236225
if ((status & VIRTIO_CONFIG_S_DRIVER_OK) &&
237226
!(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) {
238227
ret = ifcvf_request_irq(adapter);
@@ -252,6 +241,29 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
252241
ifcvf_set_status(vf, status);
253242
}
254243

244+
static int ifcvf_vdpa_reset(struct vdpa_device *vdpa_dev)
245+
{
246+
struct ifcvf_adapter *adapter;
247+
struct ifcvf_hw *vf;
248+
u8 status_old;
249+
250+
vf = vdpa_to_vf(vdpa_dev);
251+
adapter = vdpa_to_adapter(vdpa_dev);
252+
status_old = ifcvf_get_status(vf);
253+
254+
if (status_old == 0)
255+
return 0;
256+
257+
if (status_old & VIRTIO_CONFIG_S_DRIVER_OK) {
258+
ifcvf_stop_datapath(adapter);
259+
ifcvf_free_irq(adapter, vf->nr_vring);
260+
}
261+
262+
ifcvf_reset_vring(adapter);
263+
264+
return 0;
265+
}
266+
255267
static u16 ifcvf_vdpa_get_vq_num_max(struct vdpa_device *vdpa_dev)
256268
{
257269
return IFCVF_QUEUE_MAX;
@@ -435,6 +447,7 @@ static const struct vdpa_config_ops ifc_vdpa_ops = {
435447
.set_features = ifcvf_vdpa_set_features,
436448
.get_status = ifcvf_vdpa_get_status,
437449
.set_status = ifcvf_vdpa_set_status,
450+
.reset = ifcvf_vdpa_reset,
438451
.get_vq_num_max = ifcvf_vdpa_get_vq_num_max,
439452
.get_vq_state = ifcvf_vdpa_get_vq_state,
440453
.set_vq_state = ifcvf_vdpa_set_vq_state,

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,22 +2154,6 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
21542154
int err;
21552155

21562156
print_status(mvdev, status, true);
2157-
if (!status) {
2158-
mlx5_vdpa_info(mvdev, "performing device reset\n");
2159-
teardown_driver(ndev);
2160-
clear_vqs_ready(ndev);
2161-
mlx5_vdpa_destroy_mr(&ndev->mvdev);
2162-
ndev->mvdev.status = 0;
2163-
ndev->mvdev.mlx_features = 0;
2164-
memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs));
2165-
ndev->mvdev.actual_features = 0;
2166-
++mvdev->generation;
2167-
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
2168-
if (mlx5_vdpa_create_mr(mvdev, NULL))
2169-
mlx5_vdpa_warn(mvdev, "create MR failed\n");
2170-
}
2171-
return;
2172-
}
21732157

21742158
if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) {
21752159
if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
@@ -2192,6 +2176,29 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
21922176
ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
21932177
}
21942178

2179+
static int mlx5_vdpa_reset(struct vdpa_device *vdev)
2180+
{
2181+
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
2182+
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
2183+
2184+
print_status(mvdev, 0, true);
2185+
mlx5_vdpa_info(mvdev, "performing device reset\n");
2186+
teardown_driver(ndev);
2187+
clear_vqs_ready(ndev);
2188+
mlx5_vdpa_destroy_mr(&ndev->mvdev);
2189+
ndev->mvdev.status = 0;
2190+
ndev->mvdev.mlx_features = 0;
2191+
memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs));
2192+
ndev->mvdev.actual_features = 0;
2193+
++mvdev->generation;
2194+
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
2195+
if (mlx5_vdpa_create_mr(mvdev, NULL))
2196+
mlx5_vdpa_warn(mvdev, "create MR failed\n");
2197+
}
2198+
2199+
return 0;
2200+
}
2201+
21952202
static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev)
21962203
{
21972204
return sizeof(struct virtio_net_config);
@@ -2305,6 +2312,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
23052312
.get_vendor_id = mlx5_vdpa_get_vendor_id,
23062313
.get_status = mlx5_vdpa_get_status,
23072314
.set_status = mlx5_vdpa_set_status,
2315+
.reset = mlx5_vdpa_reset,
23082316
.get_config_size = mlx5_vdpa_get_config_size,
23092317
.get_config = mlx5_vdpa_get_config,
23102318
.set_config = mlx5_vdpa_set_config,

drivers/vdpa/vdpa_sim/vdpa_sim.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static void vdpasim_vq_reset(struct vdpasim *vdpasim,
9292
vq->vring.notify = NULL;
9393
}
9494

95-
static void vdpasim_reset(struct vdpasim *vdpasim)
95+
static void vdpasim_do_reset(struct vdpasim *vdpasim)
9696
{
9797
int i;
9898

@@ -460,11 +460,21 @@ static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status)
460460

461461
spin_lock(&vdpasim->lock);
462462
vdpasim->status = status;
463-
if (status == 0)
464-
vdpasim_reset(vdpasim);
465463
spin_unlock(&vdpasim->lock);
466464
}
467465

466+
static int vdpasim_reset(struct vdpa_device *vdpa)
467+
{
468+
struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
469+
470+
spin_lock(&vdpasim->lock);
471+
vdpasim->status = 0;
472+
vdpasim_do_reset(vdpasim);
473+
spin_unlock(&vdpasim->lock);
474+
475+
return 0;
476+
}
477+
468478
static size_t vdpasim_get_config_size(struct vdpa_device *vdpa)
469479
{
470480
struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
@@ -608,6 +618,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = {
608618
.get_vendor_id = vdpasim_get_vendor_id,
609619
.get_status = vdpasim_get_status,
610620
.set_status = vdpasim_set_status,
621+
.reset = vdpasim_reset,
611622
.get_config_size = vdpasim_get_config_size,
612623
.get_config = vdpasim_get_config,
613624
.set_config = vdpasim_set_config,
@@ -636,6 +647,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = {
636647
.get_vendor_id = vdpasim_get_vendor_id,
637648
.get_status = vdpasim_get_status,
638649
.set_status = vdpasim_set_status,
650+
.reset = vdpasim_reset,
639651
.get_config_size = vdpasim_get_config_size,
640652
.get_config = vdpasim_get_config,
641653
.set_config = vdpasim_set_config,

drivers/vdpa/virtio_pci/vp_vdpa.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,20 @@ static void vp_vdpa_set_status(struct vdpa_device *vdpa, u8 status)
189189
}
190190

191191
vp_modern_set_status(mdev, status);
192+
}
192193

193-
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK) &&
194-
(s & VIRTIO_CONFIG_S_DRIVER_OK))
194+
static int vp_vdpa_reset(struct vdpa_device *vdpa)
195+
{
196+
struct vp_vdpa *vp_vdpa = vdpa_to_vp(vdpa);
197+
struct virtio_pci_modern_device *mdev = &vp_vdpa->mdev;
198+
u8 s = vp_vdpa_get_status(vdpa);
199+
200+
vp_modern_set_status(mdev, 0);
201+
202+
if (s & VIRTIO_CONFIG_S_DRIVER_OK)
195203
vp_vdpa_free_irq(vp_vdpa);
204+
205+
return 0;
196206
}
197207

198208
static u16 vp_vdpa_get_vq_num_max(struct vdpa_device *vdpa)
@@ -398,6 +408,7 @@ static const struct vdpa_config_ops vp_vdpa_ops = {
398408
.set_features = vp_vdpa_set_features,
399409
.get_status = vp_vdpa_get_status,
400410
.set_status = vp_vdpa_set_status,
411+
.reset = vp_vdpa_reset,
401412
.get_vq_num_max = vp_vdpa_get_vq_num_max,
402413
.get_vq_state = vp_vdpa_get_vq_state,
403414
.get_vq_notification = vp_vdpa_get_vq_notification,

drivers/vhost/vdpa.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)
157157
struct vdpa_device *vdpa = v->vdpa;
158158
const struct vdpa_config_ops *ops = vdpa->config;
159159
u8 status, status_old;
160-
int nvqs = v->nvqs;
160+
int ret, nvqs = v->nvqs;
161161
u16 i;
162162

163163
if (copy_from_user(&status, statusp, sizeof(status)))
@@ -172,7 +172,12 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)
172172
if (status != 0 && (ops->get_status(vdpa) & ~status) != 0)
173173
return -EINVAL;
174174

175-
ops->set_status(vdpa, status);
175+
if (status == 0) {
176+
ret = ops->reset(vdpa);
177+
if (ret)
178+
return ret;
179+
} else
180+
ops->set_status(vdpa, status);
176181

177182
if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && !(status_old & VIRTIO_CONFIG_S_DRIVER_OK))
178183
for (i = 0; i < nvqs; i++)

include/linux/vdpa.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ struct vdpa_iova_range {
171171
* @set_status: Set the device status
172172
* @vdev: vdpa device
173173
* @status: virtio device status
174+
* @reset: Reset device
175+
* @vdev: vdpa device
176+
* Returns integer: success (0) or error (< 0)
174177
* @get_config_size: Get the size of the configuration space
175178
* @vdev: vdpa device
176179
* Returns size_t: configuration size
@@ -255,6 +258,7 @@ struct vdpa_config_ops {
255258
u32 (*get_vendor_id)(struct vdpa_device *vdev);
256259
u8 (*get_status)(struct vdpa_device *vdev);
257260
void (*set_status)(struct vdpa_device *vdev, u8 status);
261+
int (*reset)(struct vdpa_device *vdev);
258262
size_t (*get_config_size)(struct vdpa_device *vdev);
259263
void (*get_config)(struct vdpa_device *vdev, unsigned int offset,
260264
void *buf, unsigned int len);
@@ -348,12 +352,12 @@ static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev)
348352
return vdev->dma_dev;
349353
}
350354

351-
static inline void vdpa_reset(struct vdpa_device *vdev)
355+
static inline int vdpa_reset(struct vdpa_device *vdev)
352356
{
353357
const struct vdpa_config_ops *ops = vdev->config;
354358

355359
vdev->features_valid = false;
356-
ops->set_status(vdev, 0);
360+
return ops->reset(vdev);
357361
}
358362

359363
static inline int vdpa_set_features(struct vdpa_device *vdev, u64 features)

0 commit comments

Comments
 (0)