Skip to content

Commit b398f91

Browse files
Longfang Liuawilliam
authored andcommitted
hisi_acc_vfio_pci: register debugfs for hisilicon migration driver
On the debugfs framework of VFIO, if the CONFIG_VFIO_DEBUGFS macro is enabled, the debug function is registered for the live migration driver of the HiSilicon accelerator device. After registering the HiSilicon accelerator device on the debugfs framework of live migration of vfio, a directory file "hisi_acc" of debugfs is created, and then three debug function files are created in this directory: vfio | +---<dev_name1> | +---migration | +--state | +--hisi_acc | +--dev_data | +--migf_data | +--cmd_state | +---<dev_name2> +---migration +--state +--hisi_acc +--dev_data +--migf_data +--cmd_state dev_data file: read device data that needs to be migrated from the current device in real time migf_data file: read the migration data of the last live migration from the current driver. cmd_state: used to get the cmd channel state for the device. +----------------+ +--------------+ +---------------+ | migration dev | | src dev | | dst dev | +-------+--------+ +------+-------+ +-------+-------+ | | | | +------v-------+ +-------v-------+ | | saving_migf | | resuming_migf | read | | file | | file | | +------+-------+ +-------+-------+ | | copy | | +------------+----------+ | | +-------v--------+ +-------v--------+ | data buffer | | debug_migf | +-------+--------+ +-------+--------+ | | cat | cat | +-------v--------+ +-------v--------+ | dev_data | | migf_data | +----------------+ +----------------+ When accessing debugfs, user can obtain the most recent status data of the device through the "dev_data" file. It can read recent complete status data of the device. If the current device is being migrated, it will wait for it to complete. The data for the last completed migration function will be stored in debug_migf. Users can read it via "migf_data". Signed-off-by: Longfang Liu <[email protected]> Reviewed-by: Shameer Kolothum <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 1962920 commit b398f91

File tree

2 files changed

+210
-0
lines changed

2 files changed

+210
-0
lines changed

drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,15 +627,31 @@ static void hisi_acc_vf_disable_fd(struct hisi_acc_vf_migration_file *migf)
627627
mutex_unlock(&migf->lock);
628628
}
629629

630+
static void
631+
hisi_acc_debug_migf_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev,
632+
struct hisi_acc_vf_migration_file *src_migf)
633+
{
634+
struct hisi_acc_vf_migration_file *dst_migf = hisi_acc_vdev->debug_migf;
635+
636+
if (!dst_migf)
637+
return;
638+
639+
dst_migf->total_length = src_migf->total_length;
640+
memcpy(&dst_migf->vf_data, &src_migf->vf_data,
641+
sizeof(struct acc_vf_data));
642+
}
643+
630644
static void hisi_acc_vf_disable_fds(struct hisi_acc_vf_core_device *hisi_acc_vdev)
631645
{
632646
if (hisi_acc_vdev->resuming_migf) {
647+
hisi_acc_debug_migf_copy(hisi_acc_vdev, hisi_acc_vdev->resuming_migf);
633648
hisi_acc_vf_disable_fd(hisi_acc_vdev->resuming_migf);
634649
fput(hisi_acc_vdev->resuming_migf->filp);
635650
hisi_acc_vdev->resuming_migf = NULL;
636651
}
637652

638653
if (hisi_acc_vdev->saving_migf) {
654+
hisi_acc_debug_migf_copy(hisi_acc_vdev, hisi_acc_vdev->saving_migf);
639655
hisi_acc_vf_disable_fd(hisi_acc_vdev->saving_migf);
640656
fput(hisi_acc_vdev->saving_migf->filp);
641657
hisi_acc_vdev->saving_migf = NULL;
@@ -1292,6 +1308,129 @@ static long hisi_acc_vfio_pci_ioctl(struct vfio_device *core_vdev, unsigned int
12921308
return vfio_pci_core_ioctl(core_vdev, cmd, arg);
12931309
}
12941310

1311+
static int hisi_acc_vf_debug_check(struct seq_file *seq, struct vfio_device *vdev)
1312+
{
1313+
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(vdev);
1314+
struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
1315+
int ret;
1316+
1317+
lockdep_assert_held(&hisi_acc_vdev->open_mutex);
1318+
/*
1319+
* When the device is not opened, the io_base is not mapped.
1320+
* The driver cannot perform device read and write operations.
1321+
*/
1322+
if (!hisi_acc_vdev->dev_opened) {
1323+
seq_puts(seq, "device not opened!\n");
1324+
return -EINVAL;
1325+
}
1326+
1327+
ret = qm_wait_dev_not_ready(vf_qm);
1328+
if (ret) {
1329+
seq_puts(seq, "VF device not ready!\n");
1330+
return -EBUSY;
1331+
}
1332+
1333+
return 0;
1334+
}
1335+
1336+
static int hisi_acc_vf_debug_cmd(struct seq_file *seq, void *data)
1337+
{
1338+
struct device *vf_dev = seq->private;
1339+
struct vfio_pci_core_device *core_device = dev_get_drvdata(vf_dev);
1340+
struct vfio_device *vdev = &core_device->vdev;
1341+
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(vdev);
1342+
struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
1343+
u64 value;
1344+
int ret;
1345+
1346+
mutex_lock(&hisi_acc_vdev->open_mutex);
1347+
ret = hisi_acc_vf_debug_check(seq, vdev);
1348+
if (ret) {
1349+
mutex_unlock(&hisi_acc_vdev->open_mutex);
1350+
return ret;
1351+
}
1352+
1353+
value = readl(vf_qm->io_base + QM_MB_CMD_SEND_BASE);
1354+
if (value == QM_MB_CMD_NOT_READY) {
1355+
mutex_unlock(&hisi_acc_vdev->open_mutex);
1356+
seq_puts(seq, "mailbox cmd channel not ready!\n");
1357+
return -EINVAL;
1358+
}
1359+
mutex_unlock(&hisi_acc_vdev->open_mutex);
1360+
seq_puts(seq, "mailbox cmd channel ready!\n");
1361+
1362+
return 0;
1363+
}
1364+
1365+
static int hisi_acc_vf_dev_read(struct seq_file *seq, void *data)
1366+
{
1367+
struct device *vf_dev = seq->private;
1368+
struct vfio_pci_core_device *core_device = dev_get_drvdata(vf_dev);
1369+
struct vfio_device *vdev = &core_device->vdev;
1370+
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(vdev);
1371+
size_t vf_data_sz = offsetofend(struct acc_vf_data, padding);
1372+
struct acc_vf_data *vf_data;
1373+
int ret;
1374+
1375+
mutex_lock(&hisi_acc_vdev->open_mutex);
1376+
ret = hisi_acc_vf_debug_check(seq, vdev);
1377+
if (ret) {
1378+
mutex_unlock(&hisi_acc_vdev->open_mutex);
1379+
return ret;
1380+
}
1381+
1382+
mutex_lock(&hisi_acc_vdev->state_mutex);
1383+
vf_data = kzalloc(sizeof(*vf_data), GFP_KERNEL);
1384+
if (!vf_data) {
1385+
ret = -ENOMEM;
1386+
goto mutex_release;
1387+
}
1388+
1389+
vf_data->vf_qm_state = hisi_acc_vdev->vf_qm_state;
1390+
ret = vf_qm_read_data(&hisi_acc_vdev->vf_qm, vf_data);
1391+
if (ret)
1392+
goto migf_err;
1393+
1394+
seq_hex_dump(seq, "Dev Data:", DUMP_PREFIX_OFFSET, 16, 1,
1395+
(const void *)vf_data, vf_data_sz, false);
1396+
1397+
seq_printf(seq,
1398+
"guest driver load: %u\n"
1399+
"data size: %lu\n",
1400+
hisi_acc_vdev->vf_qm_state,
1401+
sizeof(struct acc_vf_data));
1402+
1403+
migf_err:
1404+
kfree(vf_data);
1405+
mutex_release:
1406+
mutex_unlock(&hisi_acc_vdev->state_mutex);
1407+
mutex_unlock(&hisi_acc_vdev->open_mutex);
1408+
1409+
return ret;
1410+
}
1411+
1412+
static int hisi_acc_vf_migf_read(struct seq_file *seq, void *data)
1413+
{
1414+
struct device *vf_dev = seq->private;
1415+
struct vfio_pci_core_device *core_device = dev_get_drvdata(vf_dev);
1416+
struct vfio_device *vdev = &core_device->vdev;
1417+
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(vdev);
1418+
size_t vf_data_sz = offsetofend(struct acc_vf_data, padding);
1419+
struct hisi_acc_vf_migration_file *debug_migf = hisi_acc_vdev->debug_migf;
1420+
1421+
/* Check whether the live migration operation has been performed */
1422+
if (debug_migf->total_length < QM_MATCH_SIZE) {
1423+
seq_puts(seq, "device not migrated!\n");
1424+
return -EAGAIN;
1425+
}
1426+
1427+
seq_hex_dump(seq, "Mig Data:", DUMP_PREFIX_OFFSET, 16, 1,
1428+
(const void *)&debug_migf->vf_data, vf_data_sz, false);
1429+
seq_printf(seq, "migrate data length: %lu\n", debug_migf->total_length);
1430+
1431+
return 0;
1432+
}
1433+
12951434
static int hisi_acc_vfio_pci_open_device(struct vfio_device *core_vdev)
12961435
{
12971436
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(core_vdev);
@@ -1303,12 +1442,16 @@ static int hisi_acc_vfio_pci_open_device(struct vfio_device *core_vdev)
13031442
return ret;
13041443

13051444
if (core_vdev->mig_ops) {
1445+
mutex_lock(&hisi_acc_vdev->open_mutex);
13061446
ret = hisi_acc_vf_qm_init(hisi_acc_vdev);
13071447
if (ret) {
1448+
mutex_unlock(&hisi_acc_vdev->open_mutex);
13081449
vfio_pci_core_disable(vdev);
13091450
return ret;
13101451
}
13111452
hisi_acc_vdev->mig_state = VFIO_DEVICE_STATE_RUNNING;
1453+
hisi_acc_vdev->dev_opened = true;
1454+
mutex_unlock(&hisi_acc_vdev->open_mutex);
13121455
}
13131456

13141457
vfio_pci_core_finish_enable(vdev);
@@ -1320,7 +1463,10 @@ static void hisi_acc_vfio_pci_close_device(struct vfio_device *core_vdev)
13201463
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(core_vdev);
13211464
struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
13221465

1466+
mutex_lock(&hisi_acc_vdev->open_mutex);
1467+
hisi_acc_vdev->dev_opened = false;
13231468
iounmap(vf_qm->io_base);
1469+
mutex_unlock(&hisi_acc_vdev->open_mutex);
13241470
vfio_pci_core_close_device(core_vdev);
13251471
}
13261472

@@ -1340,6 +1486,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
13401486
hisi_acc_vdev->pf_qm = pf_qm;
13411487
hisi_acc_vdev->vf_dev = pdev;
13421488
mutex_init(&hisi_acc_vdev->state_mutex);
1489+
mutex_init(&hisi_acc_vdev->open_mutex);
13431490

13441491
core_vdev->migration_flags = VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_PRE_COPY;
13451492
core_vdev->mig_ops = &hisi_acc_vfio_pci_migrn_state_ops;
@@ -1385,6 +1532,47 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_ops = {
13851532
.detach_ioas = vfio_iommufd_physical_detach_ioas,
13861533
};
13871534

1535+
static void hisi_acc_vfio_debug_init(struct hisi_acc_vf_core_device *hisi_acc_vdev)
1536+
{
1537+
struct vfio_device *vdev = &hisi_acc_vdev->core_device.vdev;
1538+
struct hisi_acc_vf_migration_file *migf;
1539+
struct dentry *vfio_dev_migration;
1540+
struct dentry *vfio_hisi_acc;
1541+
struct device *dev = vdev->dev;
1542+
1543+
if (!debugfs_initialized() ||
1544+
!IS_ENABLED(CONFIG_VFIO_DEBUGFS))
1545+
return;
1546+
1547+
if (vdev->ops != &hisi_acc_vfio_pci_migrn_ops)
1548+
return;
1549+
1550+
vfio_dev_migration = debugfs_lookup("migration", vdev->debug_root);
1551+
if (!vfio_dev_migration) {
1552+
dev_err(dev, "failed to lookup migration debugfs file!\n");
1553+
return;
1554+
}
1555+
1556+
migf = kzalloc(sizeof(*migf), GFP_KERNEL);
1557+
if (!migf)
1558+
return;
1559+
hisi_acc_vdev->debug_migf = migf;
1560+
1561+
vfio_hisi_acc = debugfs_create_dir("hisi_acc", vfio_dev_migration);
1562+
debugfs_create_devm_seqfile(dev, "dev_data", vfio_hisi_acc,
1563+
hisi_acc_vf_dev_read);
1564+
debugfs_create_devm_seqfile(dev, "migf_data", vfio_hisi_acc,
1565+
hisi_acc_vf_migf_read);
1566+
debugfs_create_devm_seqfile(dev, "cmd_state", vfio_hisi_acc,
1567+
hisi_acc_vf_debug_cmd);
1568+
}
1569+
1570+
static void hisi_acc_vf_debugfs_exit(struct hisi_acc_vf_core_device *hisi_acc_vdev)
1571+
{
1572+
kfree(hisi_acc_vdev->debug_migf);
1573+
hisi_acc_vdev->debug_migf = NULL;
1574+
}
1575+
13881576
static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
13891577
{
13901578
struct hisi_acc_vf_core_device *hisi_acc_vdev;
@@ -1411,6 +1599,8 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
14111599
ret = vfio_pci_core_register_device(&hisi_acc_vdev->core_device);
14121600
if (ret)
14131601
goto out_put_vdev;
1602+
1603+
hisi_acc_vfio_debug_init(hisi_acc_vdev);
14141604
return 0;
14151605

14161606
out_put_vdev:
@@ -1423,6 +1613,7 @@ static void hisi_acc_vfio_pci_remove(struct pci_dev *pdev)
14231613
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
14241614

14251615
vfio_pci_core_unregister_device(&hisi_acc_vdev->core_device);
1616+
hisi_acc_vf_debugfs_exit(hisi_acc_vdev);
14261617
vfio_put_device(&hisi_acc_vdev->core_device.vdev);
14271618
}
14281619

drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define QM_SQC_VFT_BASE_MASK_V2 GENMASK(15, 0)
3333
#define QM_SQC_VFT_NUM_SHIFT_V2 45
3434
#define QM_SQC_VFT_NUM_MASK_V2 GENMASK(9, 0)
35+
#define QM_MB_CMD_NOT_READY 0xffffffff
3536

3637
/* RW regs */
3738
#define QM_REGS_MAX_LEN 7
@@ -99,6 +100,13 @@ struct hisi_acc_vf_migration_file {
99100
struct hisi_acc_vf_core_device {
100101
struct vfio_pci_core_device core_device;
101102
u8 match_done;
103+
/*
104+
* io_base is only valid when dev_opened is true,
105+
* which is protected by open_mutex.
106+
*/
107+
bool dev_opened;
108+
/* Ensure the accuracy of dev_opened operation */
109+
struct mutex open_mutex;
102110

103111
/* For migration state */
104112
struct mutex state_mutex;
@@ -107,9 +115,20 @@ struct hisi_acc_vf_core_device {
107115
struct pci_dev *vf_dev;
108116
struct hisi_qm *pf_qm;
109117
struct hisi_qm vf_qm;
118+
/*
119+
* vf_qm_state represents the QM_VF_STATE register value.
120+
* It is set by Guest driver for the ACC VF dev indicating
121+
* the driver has loaded and configured the dev correctly.
122+
*/
110123
u32 vf_qm_state;
111124
int vf_id;
112125
struct hisi_acc_vf_migration_file *resuming_migf;
113126
struct hisi_acc_vf_migration_file *saving_migf;
127+
128+
/*
129+
* It holds migration data corresponding to the last migration
130+
* and is used by the debugfs interface to report it.
131+
*/
132+
struct hisi_acc_vf_migration_file *debug_migf;
114133
};
115134
#endif /* HISI_ACC_VFIO_PCI_H */

0 commit comments

Comments
 (0)