27
27
#include "hw/qdev-properties.h"
28
28
#include "hw/scsi/scsi.h"
29
29
#include "scsi/constants.h"
30
+ #include "hw/virtio/iothread-vq-mapping.h"
30
31
#include "hw/virtio/virtio-bus.h"
31
32
#include "hw/virtio/virtio-access.h"
32
33
#include "trace.h"
@@ -318,13 +319,6 @@ static void virtio_scsi_cancel_notify(Notifier *notifier, void *data)
318
319
g_free (n );
319
320
}
320
321
321
- static inline void virtio_scsi_ctx_check (VirtIOSCSI * s , SCSIDevice * d )
322
- {
323
- if (s -> dataplane_started && d && blk_is_available (d -> conf .blk )) {
324
- assert (blk_get_aio_context (d -> conf .blk ) == s -> ctx );
325
- }
326
- }
327
-
328
322
static void virtio_scsi_do_one_tmf_bh (VirtIOSCSIReq * req )
329
323
{
330
324
VirtIOSCSI * s = req -> dev ;
@@ -517,9 +511,11 @@ static void virtio_scsi_flush_defer_tmf_to_aio_context(VirtIOSCSI *s)
517
511
518
512
assert (!s -> dataplane_started );
519
513
520
- if (s -> ctx ) {
514
+ for (uint32_t i = 0 ; i < s -> parent_obj .conf .num_queues ; i ++ ) {
515
+ AioContext * ctx = s -> vq_aio_context [VIRTIO_SCSI_VQ_NUM_FIXED + i ];
516
+
521
517
/* Our BH only runs after previously scheduled BHs */
522
- aio_wait_bh_oneshot (s -> ctx , dummy_bh , NULL );
518
+ aio_wait_bh_oneshot (ctx , dummy_bh , NULL );
523
519
}
524
520
}
525
521
@@ -575,7 +571,6 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
575
571
AioContext * ctx ;
576
572
int ret = 0 ;
577
573
578
- virtio_scsi_ctx_check (s , d );
579
574
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
580
575
req -> resp .tmf .response = VIRTIO_SCSI_S_OK ;
581
576
@@ -639,6 +634,8 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
639
634
640
635
case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET :
641
636
case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET : {
637
+ g_autoptr (GHashTable ) aio_contexts = g_hash_table_new (NULL , NULL );
638
+
642
639
if (!d ) {
643
640
goto fail ;
644
641
}
@@ -648,8 +645,15 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
648
645
649
646
qatomic_inc (& req -> remaining );
650
647
651
- ctx = s -> ctx ?: qemu_get_aio_context ();
652
- virtio_scsi_defer_tmf_to_aio_context (req , ctx );
648
+ for (uint32_t i = 0 ; i < s -> parent_obj .conf .num_queues ; i ++ ) {
649
+ ctx = s -> vq_aio_context [VIRTIO_SCSI_VQ_NUM_FIXED + i ];
650
+
651
+ if (!g_hash_table_add (aio_contexts , ctx )) {
652
+ continue ; /* skip previously added AioContext */
653
+ }
654
+
655
+ virtio_scsi_defer_tmf_to_aio_context (req , ctx );
656
+ }
653
657
654
658
virtio_scsi_tmf_dec_remaining (req );
655
659
ret = - EINPROGRESS ;
@@ -770,9 +774,12 @@ static void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
770
774
*/
771
775
static bool virtio_scsi_defer_to_dataplane (VirtIOSCSI * s )
772
776
{
773
- if (! s -> ctx || s -> dataplane_started ) {
777
+ if (s -> dataplane_started ) {
774
778
return false;
775
779
}
780
+ if (s -> vq_aio_context [0 ] == qemu_get_aio_context ()) {
781
+ return false; /* not using IOThreads */
782
+ }
776
783
777
784
virtio_device_start_ioeventfd (& s -> parent_obj .parent_obj );
778
785
return !s -> dataplane_fenced ;
@@ -946,7 +953,6 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
946
953
virtio_scsi_complete_cmd_req (req );
947
954
return - ENOENT ;
948
955
}
949
- virtio_scsi_ctx_check (s , d );
950
956
req -> sreq = scsi_req_new (d , req -> req .cmd .tag ,
951
957
virtio_scsi_get_lun (req -> req .cmd .lun ),
952
958
req -> req .cmd .cdb , vs -> cdb_size , req );
@@ -1218,14 +1224,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
1218
1224
{
1219
1225
VirtIODevice * vdev = VIRTIO_DEVICE (hotplug_dev );
1220
1226
VirtIOSCSI * s = VIRTIO_SCSI (vdev );
1227
+ AioContext * ctx = s -> vq_aio_context [VIRTIO_SCSI_VQ_NUM_FIXED ];
1221
1228
SCSIDevice * sd = SCSI_DEVICE (dev );
1222
- int ret ;
1223
1229
1224
- if (s -> ctx && !s -> dataplane_fenced ) {
1225
- ret = blk_set_aio_context (sd -> conf .blk , s -> ctx , errp );
1226
- if (ret < 0 ) {
1227
- return ;
1228
- }
1230
+ if (ctx != qemu_get_aio_context () && !s -> dataplane_fenced ) {
1231
+ /*
1232
+ * Try to make the BlockBackend's AioContext match ours. Ignore failure
1233
+ * because I/O will still work although block jobs and other users
1234
+ * might be slower when multiple AioContexts use a BlockBackend.
1235
+ */
1236
+ blk_set_aio_context (sd -> conf .blk , ctx , NULL );
1229
1237
}
1230
1238
1231
1239
if (virtio_vdev_has_feature (vdev , VIRTIO_SCSI_F_HOTPLUG )) {
@@ -1260,7 +1268,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
1260
1268
1261
1269
qdev_simple_device_unplug_cb (hotplug_dev , dev , errp );
1262
1270
1263
- if (s -> ctx ) {
1271
+ if (s -> vq_aio_context [ VIRTIO_SCSI_VQ_NUM_FIXED ] != qemu_get_aio_context () ) {
1264
1272
/* If other users keep the BlockBackend in the iothread, that's ok */
1265
1273
blk_set_aio_context (sd -> conf .blk , qemu_get_aio_context (), NULL );
1266
1274
}
@@ -1294,7 +1302,7 @@ static void virtio_scsi_drained_begin(SCSIBus *bus)
1294
1302
1295
1303
for (uint32_t i = 0 ; i < total_queues ; i ++ ) {
1296
1304
VirtQueue * vq = virtio_get_queue (vdev , i );
1297
- virtio_queue_aio_detach_host_notifier (vq , s -> ctx );
1305
+ virtio_queue_aio_detach_host_notifier (vq , s -> vq_aio_context [ i ] );
1298
1306
}
1299
1307
}
1300
1308
@@ -1320,10 +1328,12 @@ static void virtio_scsi_drained_end(SCSIBus *bus)
1320
1328
1321
1329
for (uint32_t i = 0 ; i < total_queues ; i ++ ) {
1322
1330
VirtQueue * vq = virtio_get_queue (vdev , i );
1331
+ AioContext * ctx = s -> vq_aio_context [i ];
1332
+
1323
1333
if (vq == vs -> event_vq ) {
1324
- virtio_queue_aio_attach_host_notifier_no_poll (vq , s -> ctx );
1334
+ virtio_queue_aio_attach_host_notifier_no_poll (vq , ctx );
1325
1335
} else {
1326
- virtio_queue_aio_attach_host_notifier (vq , s -> ctx );
1336
+ virtio_queue_aio_attach_host_notifier (vq , ctx );
1327
1337
}
1328
1338
}
1329
1339
}
@@ -1430,12 +1440,13 @@ void virtio_scsi_common_unrealize(DeviceState *dev)
1430
1440
virtio_cleanup (vdev );
1431
1441
}
1432
1442
1443
+ /* main loop */
1433
1444
static void virtio_scsi_device_unrealize (DeviceState * dev )
1434
1445
{
1435
1446
VirtIOSCSI * s = VIRTIO_SCSI (dev );
1436
1447
1437
1448
virtio_scsi_reset_tmf_bh (s );
1438
-
1449
+ virtio_scsi_dataplane_cleanup ( s );
1439
1450
qbus_set_hotplug_handler (BUS (& s -> bus ), NULL );
1440
1451
virtio_scsi_common_unrealize (dev );
1441
1452
qemu_mutex_destroy (& s -> tmf_bh_lock );
@@ -1460,6 +1471,8 @@ static const Property virtio_scsi_properties[] = {
1460
1471
VIRTIO_SCSI_F_CHANGE , true),
1461
1472
DEFINE_PROP_LINK ("iothread" , VirtIOSCSI , parent_obj .conf .iothread ,
1462
1473
TYPE_IOTHREAD , IOThread * ),
1474
+ DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST ("iothread-vq-mapping" , VirtIOSCSI ,
1475
+ parent_obj .conf .iothread_vq_mapping_list ),
1463
1476
};
1464
1477
1465
1478
static const VMStateDescription vmstate_virtio_scsi = {
0 commit comments