libnvdimm + device-dax for 5.12

- Fix the error code polarity for the device-dax/mapping attribute
 
 - For the device-dax and libnvdimm bus implementations stop implementing
   a useless return code for the remove() callback.
 
 - Miscellaneous cleanups
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEf41QbsdZzFdA8EfZHtKRamZ9iAIFAmA1uCkACgkQHtKRamZ9
 iALORw/9GqK3Pe7/sgCiwh9Asztj4SU9Kha2uny+lmkxCX+GXi2ETndyfUqwpTYO
 WiFEcMV8SfhEKLV/soPfixmtHN/y9QtUmdrQ70uEsIZ7vv4hE2pAHiG/TsQWX4SW
 8rXhAO7/OHsKZ2c7wTewzpbm/fmAMWIofD4lJDQLsf+CUE04nHCDossHk8RySzJP
 /JA3ZN7YecFxLJO192T5JmbIaSEX5LCAlA5UxFgPwS/19KH2MM+cyb/YD4DZi+Mn
 1hiTIqNeLlrwW/VbG7j8JFGWXOAtCFdZBmb5Ms41cR2uJOBzUv1w9wszxWtGCKRJ
 LJlPCmLXWRnAi/QBRFeJR0NHEQonO9J32E8lf3gD7vccdtgOQey8+HspL/nBtUFP
 6PYl2tsowbG4KFdayxtZ3THYGbTKEDBZUNwjdOpa/NSmTPhfVs3tHZbVBhTlRcB9
 fAjKAsbu/49QV59t5yTjZwiwS4TKn8b5PZ/kdVZJlwvuYELBr8U4qRF/QqfByESP
 KYAwhXoINoO/SBPCukCMU4BVZEiPbkMcT6Yi0HvTqUoY1FGB4XSQfMNBAHuJEfU5
 L+dhqPbvcMmkg82sMffvKXBPRmX1/ApSFXjQkqMYhiG/qc8ZiOcndFwmq4p5AnVS
 9RP0g2JSoqyfNgFr4ZD+b1WS2E/R/y2U/H57U9xMnBezxwWBMJM=
 =Tcro
 -----END PGP SIGNATURE-----

Merge tag 'libnvdimm-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm and device-dax updates from Dan Williams:

 - Fix the error code polarity for the device-dax/mapping attribute

 - For the device-dax and libnvdimm bus implementations stop
   implementing a useless return code for the remove() callback.

 - Miscellaneous cleanups

* tag 'libnvdimm-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  dax-device: Make remove callback return void
  device-dax: Drop an empty .remove callback
  device-dax: Fix error path in dax_driver_register
  device-dax: Properly handle drivers without remove callback
  device-dax: Prevent registering drivers without probe callback
  libnvdimm: Make remove callback return void
  libnvdimm/dimm: Simplify nvdimm_remove()
  device-dax: Fix default return code of range_parse()
This commit is contained in:
Linus Torvalds 2021-02-24 09:35:54 -08:00
commit fb9f085488
11 changed files with 36 additions and 41 deletions

View File

@ -179,7 +179,10 @@ static int dax_bus_remove(struct device *dev)
struct dax_device_driver *dax_drv = to_dax_drv(dev->driver); struct dax_device_driver *dax_drv = to_dax_drv(dev->driver);
struct dev_dax *dev_dax = to_dev_dax(dev); struct dev_dax *dev_dax = to_dev_dax(dev);
return dax_drv->remove(dev_dax); if (dax_drv->remove)
dax_drv->remove(dev_dax);
return 0;
} }
static struct bus_type dax_bus_type = { static struct bus_type dax_bus_type = {
@ -1038,7 +1041,7 @@ static ssize_t range_parse(const char *opt, size_t len, struct range *range)
{ {
unsigned long long addr = 0; unsigned long long addr = 0;
char *start, *end, *str; char *start, *end, *str;
ssize_t rc = EINVAL; ssize_t rc = -EINVAL;
str = kstrdup(opt, GFP_KERNEL); str = kstrdup(opt, GFP_KERNEL);
if (!str) if (!str)
@ -1392,6 +1395,13 @@ int __dax_driver_register(struct dax_device_driver *dax_drv,
struct device_driver *drv = &dax_drv->drv; struct device_driver *drv = &dax_drv->drv;
int rc = 0; int rc = 0;
/*
* dax_bus_probe() calls dax_drv->probe() unconditionally.
* So better be safe than sorry and ensure it is provided.
*/
if (!dax_drv->probe)
return -EINVAL;
INIT_LIST_HEAD(&dax_drv->ids); INIT_LIST_HEAD(&dax_drv->ids);
drv->owner = module; drv->owner = module;
drv->name = mod_name; drv->name = mod_name;
@ -1409,7 +1419,15 @@ int __dax_driver_register(struct dax_device_driver *dax_drv,
mutex_unlock(&dax_bus_lock); mutex_unlock(&dax_bus_lock);
if (rc) if (rc)
return rc; return rc;
return driver_register(drv);
rc = driver_register(drv);
if (rc && dax_drv->match_always) {
mutex_lock(&dax_bus_lock);
match_always_count -= dax_drv->match_always;
mutex_unlock(&dax_bus_lock);
}
return rc;
} }
EXPORT_SYMBOL_GPL(__dax_driver_register); EXPORT_SYMBOL_GPL(__dax_driver_register);

View File

@ -39,7 +39,7 @@ struct dax_device_driver {
struct list_head ids; struct list_head ids;
int match_always; int match_always;
int (*probe)(struct dev_dax *dev); int (*probe)(struct dev_dax *dev);
int (*remove)(struct dev_dax *dev); void (*remove)(struct dev_dax *dev);
}; };
int __dax_driver_register(struct dax_device_driver *dax_drv, int __dax_driver_register(struct dax_device_driver *dax_drv,

View File

@ -452,15 +452,9 @@ int dev_dax_probe(struct dev_dax *dev_dax)
} }
EXPORT_SYMBOL_GPL(dev_dax_probe); EXPORT_SYMBOL_GPL(dev_dax_probe);
static int dev_dax_remove(struct dev_dax *dev_dax)
{
/* all probe actions are unwound by devm */
return 0;
}
static struct dax_device_driver device_dax_driver = { static struct dax_device_driver device_dax_driver = {
.probe = dev_dax_probe, .probe = dev_dax_probe,
.remove = dev_dax_remove, /* all probe actions are unwound by devm, so .remove isn't necessary */
.match_always = 1, .match_always = 1,
}; };

View File

@ -136,7 +136,7 @@ err_res_name:
} }
#ifdef CONFIG_MEMORY_HOTREMOVE #ifdef CONFIG_MEMORY_HOTREMOVE
static int dev_dax_kmem_remove(struct dev_dax *dev_dax) static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
{ {
int i, success = 0; int i, success = 0;
struct device *dev = &dev_dax->dev; struct device *dev = &dev_dax->dev;
@ -176,11 +176,9 @@ static int dev_dax_kmem_remove(struct dev_dax *dev_dax)
kfree(data); kfree(data);
dev_set_drvdata(dev, NULL); dev_set_drvdata(dev, NULL);
} }
return 0;
} }
#else #else
static int dev_dax_kmem_remove(struct dev_dax *dev_dax) static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
{ {
/* /*
* Without hotremove purposely leak the request_mem_region() for the * Without hotremove purposely leak the request_mem_region() for the
@ -190,7 +188,6 @@ static int dev_dax_kmem_remove(struct dev_dax *dev_dax)
* request_mem_region(). * request_mem_region().
*/ */
any_hotremove_failed = true; any_hotremove_failed = true;
return 0;
} }
#endif /* CONFIG_MEMORY_HOTREMOVE */ #endif /* CONFIG_MEMORY_HOTREMOVE */

View File

@ -41,10 +41,9 @@ static int dax_pmem_compat_release(struct device *dev, void *data)
return 0; return 0;
} }
static int dax_pmem_compat_remove(struct device *dev) static void dax_pmem_compat_remove(struct device *dev)
{ {
device_for_each_child(dev, NULL, dax_pmem_compat_release); device_for_each_child(dev, NULL, dax_pmem_compat_release);
return 0;
} }
static struct nd_device_driver dax_pmem_compat_driver = { static struct nd_device_driver dax_pmem_compat_driver = {

View File

@ -310,11 +310,10 @@ static int nd_blk_probe(struct device *dev)
return nsblk_attach_disk(nsblk); return nsblk_attach_disk(nsblk);
} }
static int nd_blk_remove(struct device *dev) static void nd_blk_remove(struct device *dev)
{ {
if (is_nd_btt(dev)) if (is_nd_btt(dev))
nvdimm_namespace_detach_btt(to_nd_btt(dev)); nvdimm_namespace_detach_btt(to_nd_btt(dev));
return 0;
} }
static struct nd_device_driver nd_blk_driver = { static struct nd_device_driver nd_blk_driver = {

View File

@ -113,18 +113,17 @@ static int nvdimm_bus_remove(struct device *dev)
struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver); struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
struct module *provider = to_bus_provider(dev); struct module *provider = to_bus_provider(dev);
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
int rc = 0;
if (nd_drv->remove) { if (nd_drv->remove) {
debug_nvdimm_lock(dev); debug_nvdimm_lock(dev);
rc = nd_drv->remove(dev); nd_drv->remove(dev);
debug_nvdimm_unlock(dev); debug_nvdimm_unlock(dev);
} }
dev_dbg(&nvdimm_bus->dev, "%s.remove(%s) = %d\n", dev->driver->name, dev_dbg(&nvdimm_bus->dev, "%s.remove(%s)\n", dev->driver->name,
dev_name(dev), rc); dev_name(dev));
module_put(provider); module_put(provider);
return rc; return 0;
} }
static void nvdimm_bus_shutdown(struct device *dev) static void nvdimm_bus_shutdown(struct device *dev)
@ -427,7 +426,7 @@ static void free_badrange_list(struct list_head *badrange_list)
list_del_init(badrange_list); list_del_init(badrange_list);
} }
static int nd_bus_remove(struct device *dev) static void nd_bus_remove(struct device *dev)
{ {
struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev); struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
@ -446,8 +445,6 @@ static int nd_bus_remove(struct device *dev)
spin_unlock(&nvdimm_bus->badrange.lock); spin_unlock(&nvdimm_bus->badrange.lock);
nvdimm_bus_destroy_ndctl(nvdimm_bus); nvdimm_bus_destroy_ndctl(nvdimm_bus);
return 0;
} }
static int nd_bus_probe(struct device *dev) static int nd_bus_probe(struct device *dev)

View File

@ -113,19 +113,14 @@ static int nvdimm_probe(struct device *dev)
return rc; return rc;
} }
static int nvdimm_remove(struct device *dev) static void nvdimm_remove(struct device *dev)
{ {
struct nvdimm_drvdata *ndd = dev_get_drvdata(dev); struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
if (!ndd)
return 0;
nvdimm_bus_lock(dev); nvdimm_bus_lock(dev);
dev_set_drvdata(dev, NULL); dev_set_drvdata(dev, NULL);
nvdimm_bus_unlock(dev); nvdimm_bus_unlock(dev);
put_ndd(ndd); put_ndd(ndd);
return 0;
} }
static struct nd_device_driver nvdimm_driver = { static struct nd_device_driver nvdimm_driver = {

View File

@ -563,7 +563,7 @@ static int nd_pmem_probe(struct device *dev)
return pmem_attach_disk(dev, ndns); return pmem_attach_disk(dev, ndns);
} }
static int nd_pmem_remove(struct device *dev) static void nd_pmem_remove(struct device *dev)
{ {
struct pmem_device *pmem = dev_get_drvdata(dev); struct pmem_device *pmem = dev_get_drvdata(dev);
@ -578,8 +578,6 @@ static int nd_pmem_remove(struct device *dev)
pmem->bb_state = NULL; pmem->bb_state = NULL;
} }
nvdimm_flush(to_nd_region(dev->parent), NULL); nvdimm_flush(to_nd_region(dev->parent), NULL);
return 0;
} }
static void nd_pmem_shutdown(struct device *dev) static void nd_pmem_shutdown(struct device *dev)

View File

@ -87,7 +87,7 @@ static int child_unregister(struct device *dev, void *data)
return 0; return 0;
} }
static int nd_region_remove(struct device *dev) static void nd_region_remove(struct device *dev)
{ {
struct nd_region *nd_region = to_nd_region(dev); struct nd_region *nd_region = to_nd_region(dev);
@ -108,8 +108,6 @@ static int nd_region_remove(struct device *dev)
*/ */
sysfs_put(nd_region->bb_state); sysfs_put(nd_region->bb_state);
nd_region->bb_state = NULL; nd_region->bb_state = NULL;
return 0;
} }
static int child_notify(struct device *dev, void *data) static int child_notify(struct device *dev, void *data)

View File

@ -26,7 +26,7 @@ struct nd_device_driver {
struct device_driver drv; struct device_driver drv;
unsigned long type; unsigned long type;
int (*probe)(struct device *dev); int (*probe)(struct device *dev);
int (*remove)(struct device *dev); void (*remove)(struct device *dev);
void (*shutdown)(struct device *dev); void (*shutdown)(struct device *dev);
void (*notify)(struct device *dev, enum nvdimm_event event); void (*notify)(struct device *dev, enum nvdimm_event event);
}; };