Skip to content

Commit 9261f04

Browse files
Tony Krowiakhcahca
authored andcommitted
s390/vfio-ap: use work struct to verify queue reset
Instead of waiting to verify that a queue is reset in the vfio_ap_mdev_reset_queue function, let's use a wait queue to check the the state of the reset. This way, when resetting all of the queues assigned to a matrix mdev, we don't have to wait for each queue to be reset before initiating a reset on the next queue to be reset. Signed-off-by: Tony Krowiak <[email protected]> Reviewed-by: Jason J. Herne <[email protected]> Suggested-by: Halil Pasic <[email protected]> Acked-by: Janosch Frank <[email protected]> Tested-by: Viktor Mihajlovski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Heiko Carstens <[email protected]>
1 parent 62aab08 commit 9261f04

File tree

2 files changed

+25
-25
lines changed

2 files changed

+25
-25
lines changed

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
static int vfio_ap_mdev_reset_queues(struct ap_queue_table *qtable);
3636
static struct vfio_ap_queue *vfio_ap_find_queue(int apqn);
3737
static const struct vfio_device_ops vfio_ap_matrix_dev_ops;
38-
static int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q);
38+
static void vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q);
3939

4040
/**
4141
* get_update_locks_for_kvm: Acquire the locks required to dynamically update a
@@ -1623,19 +1623,21 @@ static int apq_status_check(int apqn, struct ap_queue_status *status)
16231623

16241624
#define WAIT_MSG "Waited %dms for reset of queue %02x.%04x (%u, %u, %u)"
16251625

1626-
static int apq_reset_check(struct vfio_ap_queue *q)
1626+
static void apq_reset_check(struct work_struct *reset_work)
16271627
{
16281628
int ret = -EBUSY, elapsed = 0;
16291629
struct ap_queue_status status;
1630+
struct vfio_ap_queue *q;
16301631

1632+
q = container_of(reset_work, struct vfio_ap_queue, reset_work);
16311633
memcpy(&status, &q->reset_status, sizeof(status));
16321634
while (true) {
16331635
msleep(AP_RESET_INTERVAL);
16341636
elapsed += AP_RESET_INTERVAL;
16351637
status = ap_tapq(q->apqn, NULL);
16361638
ret = apq_status_check(q->apqn, &status);
16371639
if (ret == -EIO)
1638-
return ret;
1640+
return;
16391641
if (ret == -EBUSY) {
16401642
pr_notice_ratelimited(WAIT_MSG, elapsed,
16411643
AP_QID_CARD(q->apqn),
@@ -1663,64 +1665,58 @@ static int apq_reset_check(struct vfio_ap_queue *q)
16631665
break;
16641666
}
16651667
}
1666-
return ret;
16671668
}
16681669

1669-
static int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q)
1670+
static void vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q)
16701671
{
16711672
struct ap_queue_status status;
1672-
int ret = 0;
16731673

16741674
if (!q)
1675-
return 0;
1675+
return;
16761676
status = ap_zapq(q->apqn, 0);
16771677
memcpy(&q->reset_status, &status, sizeof(status));
16781678
switch (status.response_code) {
16791679
case AP_RESPONSE_NORMAL:
16801680
case AP_RESPONSE_RESET_IN_PROGRESS:
16811681
case AP_RESPONSE_BUSY:
1682-
/* Let's verify whether the ZAPQ completed successfully */
1683-
ret = apq_reset_check(q);
1682+
/*
1683+
* Let's verify whether the ZAPQ completed successfully on a work queue.
1684+
*/
1685+
queue_work(system_long_wq, &q->reset_work);
16841686
break;
16851687
case AP_RESPONSE_DECONFIGURED:
16861688
/*
16871689
* When an AP adapter is deconfigured, the associated
16881690
* queues are reset, so let's set the status response code to 0
1689-
* so the queue may be passed through (i.e., not filtered) and
1690-
* return a value indicating the reset completed successfully.
1691+
* so the queue may be passed through (i.e., not filtered).
16911692
*/
16921693
q->reset_status.response_code = 0;
1693-
ret = 0;
16941694
vfio_ap_free_aqic_resources(q);
16951695
break;
16961696
default:
16971697
WARN(true,
16981698
"PQAP/ZAPQ for %02x.%04x failed with invalid rc=%u\n",
16991699
AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn),
17001700
status.response_code);
1701-
return -EIO;
17021701
}
1703-
1704-
return ret;
17051702
}
17061703

17071704
static int vfio_ap_mdev_reset_queues(struct ap_queue_table *qtable)
17081705
{
1709-
int ret, loop_cursor, rc = 0;
1706+
int ret = 0, loop_cursor;
17101707
struct vfio_ap_queue *q;
17111708

1709+
hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode)
1710+
vfio_ap_mdev_reset_queue(q);
1711+
17121712
hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) {
1713-
ret = vfio_ap_mdev_reset_queue(q);
1714-
/*
1715-
* Regardless whether a queue turns out to be busy, or
1716-
* is not operational, we need to continue resetting
1717-
* the remaining queues.
1718-
*/
1719-
if (ret)
1720-
rc = ret;
1713+
flush_work(&q->reset_work);
1714+
1715+
if (q->reset_status.response_code)
1716+
ret = -EIO;
17211717
}
17221718

1723-
return rc;
1719+
return ret;
17241720
}
17251721

17261722
static int vfio_ap_mdev_open_device(struct vfio_device *vdev)
@@ -2045,6 +2041,7 @@ int vfio_ap_mdev_probe_queue(struct ap_device *apdev)
20452041
q->apqn = to_ap_queue(&apdev->device)->qid;
20462042
q->saved_isc = VFIO_AP_ISC_INVALID;
20472043
memset(&q->reset_status, 0, sizeof(q->reset_status));
2044+
INIT_WORK(&q->reset_work, apq_reset_check);
20482045
matrix_mdev = get_update_locks_by_apqn(q->apqn);
20492046

20502047
if (matrix_mdev) {
@@ -2094,6 +2091,7 @@ void vfio_ap_mdev_remove_queue(struct ap_device *apdev)
20942091
}
20952092

20962093
vfio_ap_mdev_reset_queue(q);
2094+
flush_work(&q->reset_work);
20972095
dev_set_drvdata(&apdev->device, NULL);
20982096
kfree(q);
20992097
release_update_locks_for_mdev(matrix_mdev);

drivers/s390/crypto/vfio_ap_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ struct ap_matrix_mdev {
134134
* @saved_isc: the guest ISC registered with the GIB interface
135135
* @mdev_qnode: allows the vfio_ap_queue struct to be added to a hashtable
136136
* @reset_status: the status from the last reset of the queue
137+
* @reset_work: work to wait for queue reset to complete
137138
*/
138139
struct vfio_ap_queue {
139140
struct ap_matrix_mdev *matrix_mdev;
@@ -143,6 +144,7 @@ struct vfio_ap_queue {
143144
unsigned char saved_isc;
144145
struct hlist_node mdev_qnode;
145146
struct ap_queue_status reset_status;
147+
struct work_struct reset_work;
146148
};
147149

148150
int vfio_ap_mdev_register(void);

0 commit comments

Comments
 (0)