mm/hmm/test: fix error handling in dmirror_device_init

dmirror_device_init() calls device_initialize() which sets the device
reference count to 1, but fails to call put_device() when error occurs
after dev_set_name() or cdev_device_add() failures.  This results in
memory leaks of struct device objects.  Additionally,
dmirror_device_remove() lacks the final put_device() call to properly
release the device reference.

Found by code review.

Link: https://lkml.kernel.org/r/20251108115346.6368-1-make24@iscas.ac.cn
Fixes: 6a760f58c7 ("mm/hmm/test: use char dev with struct device to get device node")
Signed-off-by: Ma Ke <make24@iscas.ac.cn>
Cc: Haoxiang Li <make24@iscas.ac.cn>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Mika Penttilä <mpenttil@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Ma Ke 2025-11-08 19:53:46 +08:00 committed by Andrew Morton
parent 50d0598cf2
commit fe9d31fd1a
1 changed files with 7 additions and 2 deletions

View File

@ -1740,20 +1740,25 @@ static int dmirror_device_init(struct dmirror_device *mdevice, int id)
ret = dev_set_name(&mdevice->device, "hmm_dmirror%u", id); ret = dev_set_name(&mdevice->device, "hmm_dmirror%u", id);
if (ret) if (ret)
return ret; goto put_device;
ret = cdev_device_add(&mdevice->cdevice, &mdevice->device); ret = cdev_device_add(&mdevice->cdevice, &mdevice->device);
if (ret) if (ret)
return ret; goto put_device;
/* Build a list of free ZONE_DEVICE struct pages */ /* Build a list of free ZONE_DEVICE struct pages */
return dmirror_allocate_chunk(mdevice, NULL, false); return dmirror_allocate_chunk(mdevice, NULL, false);
put_device:
put_device(&mdevice->device);
return ret;
} }
static void dmirror_device_remove(struct dmirror_device *mdevice) static void dmirror_device_remove(struct dmirror_device *mdevice)
{ {
dmirror_device_remove_chunks(mdevice); dmirror_device_remove_chunks(mdevice);
cdev_device_del(&mdevice->cdevice, &mdevice->device); cdev_device_del(&mdevice->cdevice, &mdevice->device);
put_device(&mdevice->device);
} }
static int __init hmm_dmirror_init(void) static int __init hmm_dmirror_init(void)