Skip to content

Commit 2202844

Browse files
Longfang LiuAlex Williamson
authored andcommitted
vfio/migration: Add debugfs to live migration driver
There are multiple devices, software and operational steps involved in the process of live migration. An error occurred on any node may cause the live migration operation to fail. This complex process makes it very difficult to locate and analyze the cause when the function fails. In order to quickly locate the cause of the problem when the live migration fails, I added a set of debugfs to the vfio live migration driver. +-------------------------------------------+ | | | | | QEMU | | | | | +---+----------------------------+----------+ | ^ | ^ | | | | | | | | v | v | +---------+--+ +---------+--+ |src vfio_dev| |dst vfio_dev| +--+---------+ +--+---------+ | ^ | ^ | | | | v | | | +-----------+----+ +-----------+----+ |src dev debugfs | |dst dev debugfs | +----------------+ +----------------+ The entire debugfs directory will be based on the definition of the CONFIG_DEBUG_FS macro. If this macro is not enabled, the interfaces in vfio.h will be empty definitions, and the creation and initialization of the debugfs directory will not be executed. vfio | +---<dev_name1> | +---migration | +--state | +---<dev_name2> +---migration +--state debugfs will create a public root directory "vfio" file. then create a dev_name() file for each live migration device. First, create a unified state acquisition file of "migration" in this device directory. Then, create a public live migration state lookup file "state". Signed-off-by: Longfang Liu <liulongfang@huawei.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/r/20231106072225.28577-2-liulongfang@huawei.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 33cc938 commit 2202844

7 files changed

Lines changed: 129 additions & 0 deletions

File tree

drivers/vfio/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ config VFIO_VIRQFD
8080
select EVENTFD
8181
default n
8282

83+
config VFIO_DEBUGFS
84+
bool "Export VFIO internals in DebugFS"
85+
depends on DEBUG_FS
86+
help
87+
Allows exposure of VFIO device internals. This option enables
88+
the use of debugfs by VFIO drivers as required. The device can
89+
cause the VFIO code create a top-level debug/vfio directory
90+
during initialization, and then populate a subdirectory with
91+
entries as required.
92+
8393
source "drivers/vfio/pci/Kconfig"
8494
source "drivers/vfio/platform/Kconfig"
8595
source "drivers/vfio/mdev/Kconfig"

drivers/vfio/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ vfio-$(CONFIG_VFIO_GROUP) += group.o
77
vfio-$(CONFIG_IOMMUFD) += iommufd.o
88
vfio-$(CONFIG_VFIO_CONTAINER) += container.o
99
vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o
10+
vfio-$(CONFIG_VFIO_DEBUGFS) += debugfs.o
1011

1112
obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
1213
obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o

drivers/vfio/debugfs.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (c) 2023, HiSilicon Ltd.
4+
*/
5+
6+
#include <linux/device.h>
7+
#include <linux/debugfs.h>
8+
#include <linux/seq_file.h>
9+
#include <linux/vfio.h>
10+
#include "vfio.h"
11+
12+
static struct dentry *vfio_debugfs_root;
13+
14+
static int vfio_device_state_read(struct seq_file *seq, void *data)
15+
{
16+
struct device *vf_dev = seq->private;
17+
struct vfio_device *vdev = container_of(vf_dev,
18+
struct vfio_device, device);
19+
enum vfio_device_mig_state state;
20+
int ret;
21+
22+
BUILD_BUG_ON(VFIO_DEVICE_STATE_NR !=
23+
VFIO_DEVICE_STATE_PRE_COPY_P2P + 1);
24+
25+
ret = vdev->mig_ops->migration_get_state(vdev, &state);
26+
if (ret)
27+
return -EINVAL;
28+
29+
switch (state) {
30+
case VFIO_DEVICE_STATE_ERROR:
31+
seq_puts(seq, "ERROR\n");
32+
break;
33+
case VFIO_DEVICE_STATE_STOP:
34+
seq_puts(seq, "STOP\n");
35+
break;
36+
case VFIO_DEVICE_STATE_RUNNING:
37+
seq_puts(seq, "RUNNING\n");
38+
break;
39+
case VFIO_DEVICE_STATE_STOP_COPY:
40+
seq_puts(seq, "STOP_COPY\n");
41+
break;
42+
case VFIO_DEVICE_STATE_RESUMING:
43+
seq_puts(seq, "RESUMING\n");
44+
break;
45+
case VFIO_DEVICE_STATE_RUNNING_P2P:
46+
seq_puts(seq, "RUNNING_P2P\n");
47+
break;
48+
case VFIO_DEVICE_STATE_PRE_COPY:
49+
seq_puts(seq, "PRE_COPY\n");
50+
break;
51+
case VFIO_DEVICE_STATE_PRE_COPY_P2P:
52+
seq_puts(seq, "PRE_COPY_P2P\n");
53+
break;
54+
default:
55+
seq_puts(seq, "Invalid\n");
56+
}
57+
58+
return 0;
59+
}
60+
61+
void vfio_device_debugfs_init(struct vfio_device *vdev)
62+
{
63+
struct device *dev = &vdev->device;
64+
65+
vdev->debug_root = debugfs_create_dir(dev_name(vdev->dev),
66+
vfio_debugfs_root);
67+
68+
if (vdev->mig_ops) {
69+
struct dentry *vfio_dev_migration = NULL;
70+
71+
vfio_dev_migration = debugfs_create_dir("migration",
72+
vdev->debug_root);
73+
debugfs_create_devm_seqfile(dev, "state", vfio_dev_migration,
74+
vfio_device_state_read);
75+
}
76+
}
77+
78+
void vfio_device_debugfs_exit(struct vfio_device *vdev)
79+
{
80+
debugfs_remove_recursive(vdev->debug_root);
81+
}
82+
83+
void vfio_debugfs_create_root(void)
84+
{
85+
vfio_debugfs_root = debugfs_create_dir("vfio", NULL);
86+
}
87+
88+
void vfio_debugfs_remove_root(void)
89+
{
90+
debugfs_remove_recursive(vfio_debugfs_root);
91+
vfio_debugfs_root = NULL;
92+
}

drivers/vfio/vfio.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,4 +448,18 @@ static inline void vfio_device_put_kvm(struct vfio_device *device)
448448
}
449449
#endif
450450

451+
#ifdef CONFIG_VFIO_DEBUGFS
452+
void vfio_debugfs_create_root(void);
453+
void vfio_debugfs_remove_root(void);
454+
455+
void vfio_device_debugfs_init(struct vfio_device *vdev);
456+
void vfio_device_debugfs_exit(struct vfio_device *vdev);
457+
#else
458+
static inline void vfio_debugfs_create_root(void) { }
459+
static inline void vfio_debugfs_remove_root(void) { }
460+
461+
static inline void vfio_device_debugfs_init(struct vfio_device *vdev) { }
462+
static inline void vfio_device_debugfs_exit(struct vfio_device *vdev) { }
463+
#endif /* CONFIG_VFIO_DEBUGFS */
464+
451465
#endif

drivers/vfio/vfio_main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ static int __vfio_register_dev(struct vfio_device *device,
311311
refcount_set(&device->refcount, 1);
312312

313313
vfio_device_group_register(device);
314+
vfio_device_debugfs_init(device);
314315

315316
return 0;
316317
err_out:
@@ -378,6 +379,7 @@ void vfio_unregister_group_dev(struct vfio_device *device)
378379
}
379380
}
380381

382+
vfio_device_debugfs_exit(device);
381383
/* Balances vfio_device_set_group in register path */
382384
vfio_device_remove_group(device);
383385
}
@@ -1676,6 +1678,7 @@ static int __init vfio_init(void)
16761678
if (ret)
16771679
goto err_alloc_dev_chrdev;
16781680

1681+
vfio_debugfs_create_root();
16791682
pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
16801683
return 0;
16811684

@@ -1691,6 +1694,7 @@ static int __init vfio_init(void)
16911694

16921695
static void __exit vfio_cleanup(void)
16931696
{
1697+
vfio_debugfs_remove_root();
16941698
ida_destroy(&vfio.device_ida);
16951699
vfio_cdev_cleanup();
16961700
class_destroy(vfio.device_class);

include/linux/vfio.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ struct vfio_device {
6969
u8 iommufd_attached:1;
7070
#endif
7171
u8 cdev_opened:1;
72+
#ifdef CONFIG_DEBUG_FS
73+
/*
74+
* debug_root is a static property of the vfio_device
75+
* which must be set prior to registering the vfio_device.
76+
*/
77+
struct dentry *debug_root;
78+
#endif
7279
};
7380

7481
/**

include/uapi/linux/vfio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,7 @@ enum vfio_device_mig_state {
12191219
VFIO_DEVICE_STATE_RUNNING_P2P = 5,
12201220
VFIO_DEVICE_STATE_PRE_COPY = 6,
12211221
VFIO_DEVICE_STATE_PRE_COPY_P2P = 7,
1222+
VFIO_DEVICE_STATE_NR,
12221223
};
12231224

12241225
/**

0 commit comments

Comments
 (0)