[PATCH i-g-t] lib/igt_core: Refactor libpciaccess init/cleanup wrappers
Peter Senna Tschudin
peter.senna at intel.com
Wed Sep 11 10:27:43 UTC 2024
On 29.08.2024 09:58, Marcin Bernatowicz wrote:
> Enable reinitialization of the libpciaccess global state, necessary
> to correctly handle dynamic add/remove of PCI devices, such as the
> creation/removal of Virtual Functions (VFs). Update
> igt_pci_system_cleanup() to conditionally call pci_system_cleanup()
> based on the initialization state. Introduce igt_pci_system_reinit()
> for explicit reinitialization of the libpciaccess global state,
> particularly useful after PCI device changes, to be used in
> subsequent patches.
Please CC me on the subsequent patches.
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz at linux.intel.com>
> Cc: Adam Miszczak <adam.miszczak at linux.intel.com>
> Cc: Lukasz Laguna <lukasz.laguna at intel.com>
> Cc: Jakub Kolakowski <jakub1.kolakowski at intel.com>
> Cc: Janusz Krzysztofik <janusz.krzysztofik at linux.intel.com>
> Cc: Chris Wilson <chris.p.wilson at intel.com>
Reviewed-by: Peter Senna Tschudin <peter.senna at linux.intel.com>
> ---
> lib/igt_core.c | 42 ++++++++++++++++++++++++++++++++++++------
> lib/igt_core.h | 36 ++++++++++++++++++++++++------------
> 2 files changed, 60 insertions(+), 18 deletions(-)
>
> diff --git a/lib/igt_core.c b/lib/igt_core.c
> index 3ff3e0392..4710899bf 100644
> --- a/lib/igt_core.c
> +++ b/lib/igt_core.c
> @@ -3414,21 +3414,51 @@ void igt_srandom(void)
> }
>
> /* IGT wrappers around libpciaccess init/cleanup functions */
> +static int pci_system_initialized;
> +static pthread_mutex_t pci_system_mutex = PTHREAD_MUTEX_INITIALIZER;
> +
> +void igt_pci_system_cleanup(void)
> +{
> + pthread_mutex_lock(&pci_system_mutex);
> + if (pci_system_initialized) {
> + pci_system_cleanup();
> + pci_system_initialized = 0;
> + }
> + pthread_mutex_unlock(&pci_system_mutex);
> +}
>
> static void pci_system_exit_handler(int sig)
> {
> - pci_system_cleanup();
> + igt_pci_system_cleanup();
> }
>
> -static void __pci_system_init(void)
> +int igt_pci_system_init(void)
> {
> - if (!igt_warn_on_f(pci_system_init(), "Could not initialize libpciaccess global data\n"))
> + int ret = 0;
> + bool install_handler = false;
> +
> + pthread_mutex_lock(&pci_system_mutex);
> + if (!pci_system_initialized) {
> + ret = igt_warn_on_f(pci_system_init(),
> + "Could not initialize libpciaccess global data\n");
> + if (ret) {
> + pci_system_initialized = 0;
> + } else {
> + pci_system_initialized = 1;
> + install_handler = true;
> + }
> + }
> + pthread_mutex_unlock(&pci_system_mutex);
> +
> + if (install_handler)
> igt_install_exit_handler(pci_system_exit_handler);
> +
> + return ret;
> }
>
> -int igt_pci_system_init(void)
> +int igt_pci_system_reinit(void)
> {
> - static pthread_once_t once_control = PTHREAD_ONCE_INIT;
> + igt_pci_system_cleanup();
>
> - return pthread_once(&once_control, __pci_system_init);
> + return igt_pci_system_init();
> }
> diff --git a/lib/igt_core.h b/lib/igt_core.h
> index 06c5314bf..0d7e948a8 100644
> --- a/lib/igt_core.h
> +++ b/lib/igt_core.h
> @@ -1518,28 +1518,40 @@ void igt_kmsg(const char *format, ...);
> * igt_pci_system_init:
> * IGT wrapper around pci_system_init()
> *
> - * Runs pci_system_init() and installs pci_system_cleanup() as IGT exit handler when
> - * called first per thread, subsequent calls are noop. Tests should use this wrapper
> + * Runs pci_system_init() and installs igt_pci_system_cleanup() as IGT exit handler when
> + * called first per thread, subsequent calls are noop. Tests should use this wrapper
> * instead of pci_system_init() to avoid memory leaking which happens each time a call
> * to pci_system_init() is repeated not preceded by pci_system_cleanup() (may easily
> * happen in consequence of long jumps performed by IGT flow control functions).
> *
> - * Return value: equal return value of pthread_once() (return value of pci_system_init()
> - * can't be passed through pthread_once())
> + * Return:
> + * Return value of pci_system_init() or 0 if pci system is already initialized.
> */
> int igt_pci_system_init(void);
>
> +/**
> + * igt_pci_system_reinit:
> + * Reinitialize libpciaccess global data.
> + *
> + * Executes igt_pci_system_cleanup() and igt_pci_system_init() to refresh
> + * the PCI system state, typically needed after PCI devices are added or
> + * removed.
> + *
> + * Note: All previously obtained handles (pci_dev, mmio) become invalid
> + * after this call. Do not use old handles post-reinitialization.
> + *
> + * Return: Outcome of igt_pci_system_init().
> + */
> +int igt_pci_system_reinit(void);
> +
> /**
> * igt_pci_system_cleanup():
> - * IGT replacement for pci_system_cleanup()
> + * IGT wrapper around pci_system_cleanup()
> *
> - * For use in IGT library and tests to avoid destroying libpciaccess global data.
> - * Direct calls to pci_system_cleanup() should be either dropped or replaced with this
> - * wrapper (for code clarity), otherwise subsequent access to libpciaccess global data
> - * may be lost unless preceded by direct call to pci_system_init() (not recommended).
> + * Runs pci_system_cleanup() if igt_pci_system_init() was successfully called
> + * before. This allows to refresh the libpciaccess global data when followed
> + * by igt_pci_system_init(), see igt_pci_system_reinit().
> */
> -static inline void igt_pci_system_cleanup(void)
> -{
> -}
> +void igt_pci_system_cleanup(void);
>
> #endif /* IGT_CORE_H */
Intel Semiconductor AG
Registered No. 020.30.913.786-7
Registered Office: Dufourstrasse 101 , 8008 Zurich, Switzerland
More information about the igt-dev
mailing list