linuxkpi: Allow ida_destroy and idr_destroy to be called multiple times

This fixes some weird behavior triggered by nvidia-drm.ko: some DRM
cleanup functions will be called multiple times, leading to a double
free. drm_mode_config_cleanup will be called twice, causing ida_destroy
to be called twice. Although calling the cleanup twice doesn't seem
very clean, on Linux this seems to be permissable as it handles it
just fine. Not doing these checks causes mutex panics and double frees.

In order to preserve this behavior this change checks if the objects
have already been destroyed and bails if so. This fixes the panic seen
when unloading the nvidia-drm driver.

MFC after:	1 week
Reviewed by:	bz, manu
Differential revision:	https://reviews.freebsd.org/D44865
This commit is contained in:
Austin Shafer 2024-06-06 23:42:06 +03:00 committed by Vladimir Kondratyev
parent 21f4cf5ccf
commit 613723bac2

View file

@ -178,6 +178,14 @@ idr_destroy(struct idr *idr)
{
struct idr_layer *il, *iln;
/*
* This idr can be reused, and this function might be called multiple times
* without a idr_init(). Check if this is the case. If we do not do this
* then the mutex will panic while asserting that it is valid.
*/
if (mtx_initialized(&idr->lock) == 0)
return;
idr_remove_all(idr);
mtx_lock(&idr->lock);
for (il = idr->free; il != NULL; il = iln) {
@ -802,4 +810,5 @@ ida_destroy(struct ida *ida)
{
idr_destroy(&ida->idr);
free(ida->free_bitmap, M_IDR);
ida->free_bitmap = NULL;
}