From dde0a31863d6a7b05ca7cb5d138586e71afc5e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 13 Jul 2021 21:35:18 +0200 Subject: PCI: endpoint: Make struct pci_epf_driver::remove return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ignores the return value of pci_epf_device_remove() (because there is only little it can do when a device disappears) and there are no pci_epf_drivers with a remove callback. So make it impossible for future drivers to return an unused error code by changing the remove prototype to return void. The real motivation for this change is the quest to make struct bus_type::remove return void, too. Acked-by: Kishon Vijay Abraham I Acked-by: Bjorn Helgaas Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210713193522.1770306-2-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/pci/endpoint/pci-epf-core.c | 5 ++--- include/linux/pci-epf.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index e9289d10f822..4b9ad96bf1b2 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -389,15 +389,14 @@ static int pci_epf_device_probe(struct device *dev) static int pci_epf_device_remove(struct device *dev) { - int ret = 0; struct pci_epf *epf = to_pci_epf(dev); struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver); if (driver->remove) - ret = driver->remove(epf); + driver->remove(epf); epf->driver = NULL; - return ret; + return 0; } static struct bus_type pci_epf_bus_type = { diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index 2debc27ba95e..8292420426f3 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -85,7 +85,7 @@ struct pci_epf_ops { */ struct pci_epf_driver { int (*probe)(struct pci_epf *epf); - int (*remove)(struct pci_epf *epf); + void (*remove)(struct pci_epf *epf); struct device_driver driver; struct pci_epf_ops *ops; -- cgit v1.2.1 From a7bdb9a9767360c2b4096bbb379e73022b274483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 13 Jul 2021 21:35:19 +0200 Subject: s390/cio: Make struct css_driver::remove return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ignores the return value of css_remove() (because there is only little it can do when a device disappears) and all callbacks return 0 anyhow. So make it impossible for future drivers to return an unused error code by changing the remove prototype to return void. The real motivation for this change is the quest to make struct bus_type::remove return void, too. Reviewed-by: Cornelia Huck Acked-by: Vineeth Vijayan Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210713193522.1770306-3-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/chsc_sch.c | 3 +-- drivers/s390/cio/css.c | 7 ++++--- drivers/s390/cio/css.h | 2 +- drivers/s390/cio/device.c | 5 ++--- drivers/s390/cio/eadm_sch.c | 4 +--- drivers/s390/cio/vfio_ccw_drv.c | 3 +-- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index c42405c620b5..684348d82f08 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -100,7 +100,7 @@ static int chsc_subchannel_probe(struct subchannel *sch) return ret; } -static int chsc_subchannel_remove(struct subchannel *sch) +static void chsc_subchannel_remove(struct subchannel *sch) { struct chsc_private *private; @@ -112,7 +112,6 @@ static int chsc_subchannel_remove(struct subchannel *sch) put_device(&sch->dev); } kfree(private); - return 0; } static void chsc_subchannel_shutdown(struct subchannel *sch) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index a974943c27da..092fd1ea5799 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1374,12 +1374,13 @@ static int css_probe(struct device *dev) static int css_remove(struct device *dev) { struct subchannel *sch; - int ret; sch = to_subchannel(dev); - ret = sch->driver->remove ? sch->driver->remove(sch) : 0; + if (sch->driver->remove) + sch->driver->remove(sch); sch->driver = NULL; - return ret; + + return 0; } static void css_shutdown(struct device *dev) diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 2eddfc47f687..c98522cbe276 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -81,7 +81,7 @@ struct css_driver { int (*chp_event)(struct subchannel *, struct chp_link *, int); int (*sch_event)(struct subchannel *, int); int (*probe)(struct subchannel *); - int (*remove)(struct subchannel *); + void (*remove)(struct subchannel *); void (*shutdown)(struct subchannel *); int (*settle)(void); }; diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 84f659cafe76..cd5d2d4d8e46 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -137,7 +137,7 @@ static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env) static void io_subchannel_irq(struct subchannel *); static int io_subchannel_probe(struct subchannel *); -static int io_subchannel_remove(struct subchannel *); +static void io_subchannel_remove(struct subchannel *); static void io_subchannel_shutdown(struct subchannel *); static int io_subchannel_sch_event(struct subchannel *, int); static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, @@ -1101,7 +1101,7 @@ out_schedule: return 0; } -static int io_subchannel_remove(struct subchannel *sch) +static void io_subchannel_remove(struct subchannel *sch) { struct io_subchannel_private *io_priv = to_io_private(sch); struct ccw_device *cdev; @@ -1120,7 +1120,6 @@ out_free: io_priv->dma_area, io_priv->dma_area_dma); kfree(io_priv); sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); - return 0; } static void io_subchannel_verify(struct subchannel *sch) diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c index c8964e0a23e7..15bdae5981ca 100644 --- a/drivers/s390/cio/eadm_sch.c +++ b/drivers/s390/cio/eadm_sch.c @@ -282,7 +282,7 @@ disable: spin_unlock_irq(sch->lock); } -static int eadm_subchannel_remove(struct subchannel *sch) +static void eadm_subchannel_remove(struct subchannel *sch) { struct eadm_private *private = get_eadm_private(sch); @@ -297,8 +297,6 @@ static int eadm_subchannel_remove(struct subchannel *sch) spin_unlock_irq(sch->lock); kfree(private); - - return 0; } static void eadm_subchannel_shutdown(struct subchannel *sch) diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 9b61e9b131ad..76099bcb765b 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -234,7 +234,7 @@ out_free: return ret; } -static int vfio_ccw_sch_remove(struct subchannel *sch) +static void vfio_ccw_sch_remove(struct subchannel *sch) { struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); struct vfio_ccw_crw *crw, *temp; @@ -257,7 +257,6 @@ static int vfio_ccw_sch_remove(struct subchannel *sch) VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n", sch->schid.cssid, sch->schid.ssid, sch->schid.sch_no); - return 0; } static void vfio_ccw_sch_shutdown(struct subchannel *sch) -- cgit v1.2.1 From 7a47c52142c18a9239c5afea2c9656c68d3f22e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 13 Jul 2021 21:35:20 +0200 Subject: s390/ccwgroup: Drop if with an always false condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core only calls a bus remove callback when there is a driver. So dev->driver is never NULL and the check can safely be removed. Reviewed-by: Cornelia Huck Acked-by: Vineeth Vijayan Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210713193522.1770306-4-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/ccwgroup.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 9748165e08e9..a6aeab1ea0ae 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -444,8 +444,6 @@ static int ccwgroup_remove(struct device *dev) struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); - if (!dev->driver) - return 0; if (gdrv->remove) gdrv->remove(gdev); -- cgit v1.2.1 From 15f83bb0191261adece5a26bfdf93c6eccdbc0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 13 Jul 2021 21:35:21 +0200 Subject: s390/scm: Make struct scm_driver::remove return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ignores the return value of scmdev_remove() (because there is only little it can do when a device disappears). So make it impossible for future drivers to return an unused error code by changing the remove prototype to return void. The real motivation for this change is the quest to make struct bus_type::remove return void, too. Reviewed-by: Cornelia Huck Acked-by: Vineeth Vijayan Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210713193522.1770306-5-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- arch/s390/include/asm/eadm.h | 2 +- drivers/s390/block/scm_drv.c | 4 +--- drivers/s390/cio/scm.c | 5 ++++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index bb63b2afdf6f..445fe4c8184a 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h @@ -105,7 +105,7 @@ enum scm_event {SCM_CHANGE, SCM_AVAIL}; struct scm_driver { struct device_driver drv; int (*probe) (struct scm_device *scmdev); - int (*remove) (struct scm_device *scmdev); + void (*remove) (struct scm_device *scmdev); void (*notify) (struct scm_device *scmdev, enum scm_event event); void (*handler) (struct scm_device *scmdev, void *data, blk_status_t error); diff --git a/drivers/s390/block/scm_drv.c b/drivers/s390/block/scm_drv.c index 3134fd6e058e..69a845eb8b1f 100644 --- a/drivers/s390/block/scm_drv.c +++ b/drivers/s390/block/scm_drv.c @@ -60,15 +60,13 @@ out: return ret; } -static int scm_remove(struct scm_device *scmdev) +static void scm_remove(struct scm_device *scmdev) { struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev); scm_blk_dev_cleanup(bdev); dev_set_drvdata(&scmdev->dev, NULL); kfree(bdev); - - return 0; } static struct scm_driver scm_drv = { diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index 9f26d4310bb3..b31711307e5a 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c @@ -33,7 +33,10 @@ static int scmdev_remove(struct device *dev) struct scm_device *scmdev = to_scm_dev(dev); struct scm_driver *scmdrv = to_scm_drv(dev->driver); - return scmdrv->remove ? scmdrv->remove(scmdev) : -ENODEV; + if (scmdrv->remove) + scmdrv->remove(scmdev); + + return 0; } static int scmdev_uevent(struct device *dev, struct kobj_uevent_env *env) -- cgit v1.2.1 From fc7a6209d5710618eb4f72a77cd81b8d694ecf89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 13 Jul 2021 21:35:22 +0200 Subject: bus: Make remove callback return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ignores the return value of this callback because there is only little it can do when a device disappears. This is the final bit of a long lasting cleanup quest where several buses were converted to also return void from their remove callback. Additionally some resource leaks were fixed that were caused by drivers returning an error code in the expectation that the driver won't go away. With struct bus_type::remove returning void it's prevented that newly implemented buses return an ignored error code and so don't anticipate wrong expectations for driver authors. Reviewed-by: Tom Rix (For fpga) Reviewed-by: Mathieu Poirier Reviewed-by: Cornelia Huck (For drivers/s390 and drivers/vfio) Acked-by: Russell King (Oracle) (For ARM, Amba and related parts) Acked-by: Mark Brown Acked-by: Chen-Yu Tsai (for sunxi-rsb) Acked-by: Pali Rohár Acked-by: Mauro Carvalho Chehab (for media) Acked-by: Hans de Goede (For drivers/platform) Acked-by: Alexandre Belloni Acked-By: Vinod Koul Acked-by: Juergen Gross (For xen) Acked-by: Lee Jones (For mfd) Acked-by: Johannes Thumshirn (For mcb) Acked-by: Johan Hovold Acked-by: Srinivas Kandagatla (For slimbus) Acked-by: Kirti Wankhede (For vfio) Acked-by: Maximilian Luz Acked-by: Heikki Krogerus (For ulpi and typec) Acked-by: Samuel Iglesias Gonsálvez (For ipack) Acked-by: Geoff Levand (For ps3) Acked-by: Yehezkel Bernat (For thunderbolt) Acked-by: Alexander Shishkin (For intel_th) Acked-by: Dominik Brodowski (For pcmcia) Acked-by: Rafael J. Wysocki (For ACPI) Acked-by: Bjorn Andersson (rpmsg and apr) Acked-by: Srinivas Pandruvada (For intel-ish-hid) Acked-by: Dan Williams (For CXL, DAX, and NVDIMM) Acked-by: William Breathitt Gray (For isa) Acked-by: Stefan Richter (For firewire) Acked-by: Benjamin Tissoires (For hid) Acked-by: Thorsten Scherer (For siox) Acked-by: Sven Van Asbroeck (For anybuss) Acked-by: Ulf Hansson (For MMC) Acked-by: Wolfram Sang # for I2C Acked-by: Sudeep Holla Acked-by: Geert Uytterhoeven Acked-by: Dmitry Torokhov Acked-by: Finn Thain Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210713193522.1770306-6-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- arch/arm/common/locomo.c | 3 +-- arch/arm/common/sa1111.c | 4 +--- arch/arm/mach-rpc/ecard.c | 4 +--- arch/mips/sgi-ip22/ip22-gio.c | 3 +-- arch/parisc/kernel/drivers.c | 5 ++--- arch/powerpc/platforms/ps3/system-bus.c | 3 +-- arch/powerpc/platforms/pseries/ibmebus.c | 3 +-- arch/powerpc/platforms/pseries/vio.c | 3 +-- arch/sparc/kernel/vio.c | 4 +--- drivers/acpi/bus.c | 3 +-- drivers/amba/bus.c | 4 +--- drivers/base/auxiliary.c | 4 +--- drivers/base/isa.c | 4 +--- drivers/base/platform.c | 4 +--- drivers/bcma/main.c | 6 ++---- drivers/bus/sunxi-rsb.c | 4 +--- drivers/cxl/core.c | 3 +-- drivers/dax/bus.c | 4 +--- drivers/dma/idxd/sysfs.c | 4 +--- drivers/firewire/core-device.c | 4 +--- drivers/firmware/arm_scmi/bus.c | 4 +--- drivers/firmware/google/coreboot_table.c | 4 +--- drivers/fpga/dfl.c | 4 +--- drivers/hid/hid-core.c | 4 +--- drivers/hid/intel-ish-hid/ishtp/bus.c | 4 +--- drivers/hv/vmbus_drv.c | 5 +---- drivers/hwtracing/intel_th/core.c | 4 +--- drivers/i2c/i2c-core-base.c | 5 +---- drivers/i3c/master.c | 4 +--- drivers/input/gameport/gameport.c | 3 +-- drivers/input/serio/serio.c | 3 +-- drivers/ipack/ipack.c | 4 +--- drivers/macintosh/macio_asic.c | 4 +--- drivers/mcb/mcb-core.c | 4 +--- drivers/media/pci/bt8xx/bttv-gpio.c | 3 +-- drivers/memstick/core/memstick.c | 3 +-- drivers/mfd/mcp-core.c | 3 +-- drivers/misc/mei/bus.c | 4 +--- drivers/misc/tifm_core.c | 3 +-- drivers/mmc/core/bus.c | 4 +--- drivers/mmc/core/sdio_bus.c | 4 +--- drivers/net/netdevsim/bus.c | 3 +-- drivers/ntb/core.c | 4 +--- drivers/ntb/ntb_transport.c | 4 +--- drivers/nubus/bus.c | 6 ++---- drivers/nvdimm/bus.c | 3 +-- drivers/pci/endpoint/pci-epf-core.c | 4 +--- drivers/pci/pci-driver.c | 3 +-- drivers/pcmcia/ds.c | 4 +--- drivers/platform/surface/aggregator/bus.c | 4 +--- drivers/platform/x86/wmi.c | 4 +--- drivers/pnp/driver.c | 3 +-- drivers/rapidio/rio-driver.c | 4 +--- drivers/rpmsg/rpmsg_core.c | 7 ++----- drivers/s390/cio/ccwgroup.c | 4 +--- drivers/s390/cio/css.c | 4 +--- drivers/s390/cio/device.c | 4 +--- drivers/s390/cio/scm.c | 4 +--- drivers/s390/crypto/ap_bus.c | 4 +--- drivers/scsi/scsi_debug.c | 3 +-- drivers/sh/superhyway/superhyway.c | 8 ++------ drivers/siox/siox-core.c | 4 +--- drivers/slimbus/core.c | 4 +--- drivers/soc/qcom/apr.c | 4 +--- drivers/spi/spi.c | 4 +--- drivers/spmi/spmi.c | 3 +-- drivers/ssb/main.c | 4 +--- drivers/staging/fieldbus/anybuss/host.c | 4 +--- drivers/staging/greybus/gbphy.c | 4 +--- drivers/target/loopback/tcm_loop.c | 5 ++--- drivers/thunderbolt/domain.c | 4 +--- drivers/tty/serdev/core.c | 4 +--- drivers/usb/common/ulpi.c | 4 +--- drivers/usb/serial/bus.c | 4 +--- drivers/usb/typec/bus.c | 4 +--- drivers/vdpa/vdpa.c | 4 +--- drivers/vfio/mdev/mdev_driver.c | 4 +--- drivers/virtio/virtio.c | 3 +-- drivers/vlynq/vlynq.c | 4 +--- drivers/vme/vme.c | 4 +--- drivers/xen/xenbus/xenbus.h | 2 +- drivers/xen/xenbus/xenbus_probe.c | 4 +--- drivers/zorro/zorro-driver.c | 3 +-- include/linux/device/bus.h | 2 +- sound/ac97/bus.c | 6 ++---- sound/aoa/soundbus/core.c | 4 +--- 86 files changed, 93 insertions(+), 243 deletions(-) diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index e45f4e4e06b6..24d21ba63030 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -834,14 +834,13 @@ static int locomo_bus_probe(struct device *dev) return ret; } -static int locomo_bus_remove(struct device *dev) +static void locomo_bus_remove(struct device *dev) { struct locomo_dev *ldev = LOCOMO_DEV(dev); struct locomo_driver *drv = LOCOMO_DRV(dev->driver); if (drv->remove) drv->remove(ldev); - return 0; } struct bus_type locomo_bus_type = { diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index ff5e0d04cb89..092a2ebc0c28 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1364,15 +1364,13 @@ static int sa1111_bus_probe(struct device *dev) return ret; } -static int sa1111_bus_remove(struct device *dev) +static void sa1111_bus_remove(struct device *dev) { struct sa1111_dev *sadev = to_sa1111_device(dev); struct sa1111_driver *drv = SA1111_DRV(dev->driver); if (drv->remove) drv->remove(sadev); - - return 0; } struct bus_type sa1111_bus_type = { diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c index 827b50f1c73e..53813f9464a2 100644 --- a/arch/arm/mach-rpc/ecard.c +++ b/arch/arm/mach-rpc/ecard.c @@ -1052,7 +1052,7 @@ static int ecard_drv_probe(struct device *dev) return ret; } -static int ecard_drv_remove(struct device *dev) +static void ecard_drv_remove(struct device *dev) { struct expansion_card *ec = ECARD_DEV(dev); struct ecard_driver *drv = ECARD_DRV(dev->driver); @@ -1067,8 +1067,6 @@ static int ecard_drv_remove(struct device *dev) ec->ops = &ecard_default_ops; barrier(); ec->irq_data = NULL; - - return 0; } /* diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c index de0768a49ee8..dfc52f661ad0 100644 --- a/arch/mips/sgi-ip22/ip22-gio.c +++ b/arch/mips/sgi-ip22/ip22-gio.c @@ -143,14 +143,13 @@ static int gio_device_probe(struct device *dev) return error; } -static int gio_device_remove(struct device *dev) +static void gio_device_remove(struct device *dev) { struct gio_device *gio_dev = to_gio_device(dev); struct gio_driver *drv = to_gio_driver(dev->driver); if (dev->driver && drv->remove) drv->remove(gio_dev); - return 0; } static void gio_device_shutdown(struct device *dev) diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 80fa0650736b..776d624a7207 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -133,14 +133,13 @@ static int parisc_driver_probe(struct device *dev) return rc; } -static int __exit parisc_driver_remove(struct device *dev) +static void __exit parisc_driver_remove(struct device *dev) { struct parisc_device *pa_dev = to_parisc_device(dev); struct parisc_driver *pa_drv = to_parisc_driver(dev->driver); + if (pa_drv->remove) pa_drv->remove(pa_dev); - - return 0; } diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 1a5665875165..cc5774c64fae 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -381,7 +381,7 @@ static int ps3_system_bus_probe(struct device *_dev) return result; } -static int ps3_system_bus_remove(struct device *_dev) +static void ps3_system_bus_remove(struct device *_dev) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); struct ps3_system_bus_driver *drv; @@ -399,7 +399,6 @@ static int ps3_system_bus_remove(struct device *_dev) __func__, __LINE__, drv->core.name); pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core)); - return 0; } static void ps3_system_bus_shutdown(struct device *_dev) diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index c6c79ef55e13..7ee3ed7d6cc2 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -366,14 +366,13 @@ static int ibmebus_bus_device_probe(struct device *dev) return error; } -static int ibmebus_bus_device_remove(struct device *dev) +static void ibmebus_bus_device_remove(struct device *dev) { struct platform_device *of_dev = to_platform_device(dev); struct platform_driver *drv = to_platform_driver(dev->driver); if (dev->driver && drv->remove) drv->remove(of_dev); - return 0; } static void ibmebus_bus_device_shutdown(struct device *dev) diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index e00f3725ec96..58283cecbd52 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -1257,7 +1257,7 @@ static int vio_bus_probe(struct device *dev) } /* convert from struct device to struct vio_dev and pass to driver. */ -static int vio_bus_remove(struct device *dev) +static void vio_bus_remove(struct device *dev) { struct vio_dev *viodev = to_vio_dev(dev); struct vio_driver *viodrv = to_vio_driver(dev->driver); @@ -1276,7 +1276,6 @@ static int vio_bus_remove(struct device *dev) vio_cmo_bus_remove(viodev); put_device(devptr); - return 0; } static void vio_bus_shutdown(struct device *dev) diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 348a88691219..01122a208f94 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -93,7 +93,7 @@ static int vio_device_probe(struct device *dev) return drv->probe(vdev, id); } -static int vio_device_remove(struct device *dev) +static void vio_device_remove(struct device *dev) { struct vio_dev *vdev = to_vio_dev(dev); struct vio_driver *drv = to_vio_driver(dev->driver); @@ -107,8 +107,6 @@ static int vio_device_remove(struct device *dev) drv->remove(vdev); } - - return 0; } static ssize_t devspec_show(struct device *dev, diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index f854bcb8d010..b941555cb5e4 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1019,7 +1019,7 @@ static int acpi_device_probe(struct device *dev) return 0; } -static int acpi_device_remove(struct device *dev) +static void acpi_device_remove(struct device *dev) { struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; @@ -1034,7 +1034,6 @@ static int acpi_device_remove(struct device *dev) acpi_dev->driver_data = NULL; put_device(dev); - return 0; } struct bus_type acpi_bus_type = { diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 939ca220bf78..962041148482 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -219,7 +219,7 @@ static int amba_probe(struct device *dev) return ret; } -static int amba_remove(struct device *dev) +static void amba_remove(struct device *dev) { struct amba_device *pcdev = to_amba_device(dev); struct amba_driver *drv = to_amba_driver(dev->driver); @@ -236,8 +236,6 @@ static int amba_remove(struct device *dev) amba_put_disable_pclk(pcdev); dev_pm_domain_detach(dev, true); - - return 0; } static void amba_shutdown(struct device *dev) diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index adc199dfba3c..0c86f5bed9f4 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -79,7 +79,7 @@ static int auxiliary_bus_probe(struct device *dev) return ret; } -static int auxiliary_bus_remove(struct device *dev) +static void auxiliary_bus_remove(struct device *dev) { struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); struct auxiliary_device *auxdev = to_auxiliary_dev(dev); @@ -87,8 +87,6 @@ static int auxiliary_bus_remove(struct device *dev) if (auxdrv->remove) auxdrv->remove(auxdev); dev_pm_domain_detach(dev, true); - - return 0; } static void auxiliary_bus_shutdown(struct device *dev) diff --git a/drivers/base/isa.c b/drivers/base/isa.c index aa4737667026..55e3ee2da98f 100644 --- a/drivers/base/isa.c +++ b/drivers/base/isa.c @@ -46,14 +46,12 @@ static int isa_bus_probe(struct device *dev) return 0; } -static int isa_bus_remove(struct device *dev) +static void isa_bus_remove(struct device *dev) { struct isa_driver *isa_driver = dev->platform_data; if (isa_driver && isa_driver->remove) isa_driver->remove(dev, to_isa_dev(dev)->id); - - return 0; } static void isa_bus_shutdown(struct device *dev) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 8640578f45e9..a94b7f454881 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1438,7 +1438,7 @@ out: return ret; } -static int platform_remove(struct device *_dev) +static void platform_remove(struct device *_dev) { struct platform_driver *drv = to_platform_driver(_dev->driver); struct platform_device *dev = to_platform_device(_dev); @@ -1450,8 +1450,6 @@ static int platform_remove(struct device *_dev) dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n"); } dev_pm_domain_detach(_dev, true); - - return 0; } static void platform_shutdown(struct device *_dev) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 6535614a7dc1..e076630d17bd 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -27,7 +27,7 @@ static DEFINE_MUTEX(bcma_buses_mutex); static int bcma_bus_match(struct device *dev, struct device_driver *drv); static int bcma_device_probe(struct device *dev); -static int bcma_device_remove(struct device *dev); +static void bcma_device_remove(struct device *dev); static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env); static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -614,7 +614,7 @@ static int bcma_device_probe(struct device *dev) return err; } -static int bcma_device_remove(struct device *dev) +static void bcma_device_remove(struct device *dev) { struct bcma_device *core = container_of(dev, struct bcma_device, dev); struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver, @@ -623,8 +623,6 @@ static int bcma_device_remove(struct device *dev) if (adrv->remove) adrv->remove(core); put_device(dev); - - return 0; } static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env) diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index d46db132d085..6f225dddc74f 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -169,13 +169,11 @@ static int sunxi_rsb_device_probe(struct device *dev) return drv->probe(rdev); } -static int sunxi_rsb_device_remove(struct device *dev) +static void sunxi_rsb_device_remove(struct device *dev) { const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver); drv->remove(to_sunxi_rsb_device(dev)); - - return 0; } static struct bus_type sunxi_rsb_bus = { diff --git a/drivers/cxl/core.c b/drivers/cxl/core.c index a2e4d54fc7bc..2b90b7c3b9d7 100644 --- a/drivers/cxl/core.c +++ b/drivers/cxl/core.c @@ -1034,13 +1034,12 @@ static int cxl_bus_probe(struct device *dev) return to_cxl_drv(dev->driver)->probe(dev); } -static int cxl_bus_remove(struct device *dev) +static void cxl_bus_remove(struct device *dev) { struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver); if (cxl_drv->remove) cxl_drv->remove(dev); - return 0; } struct bus_type cxl_bus_type = { diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index 5aee26e1bbd6..6cc4da4c713d 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -172,15 +172,13 @@ static int dax_bus_probe(struct device *dev) return 0; } -static int dax_bus_remove(struct device *dev) +static void dax_bus_remove(struct device *dev) { struct dax_device_driver *dax_drv = to_dax_drv(dev->driver); struct dev_dax *dev_dax = to_dev_dax(dev); if (dax_drv->remove) dax_drv->remove(dev_dax); - - return 0; } static struct bus_type dax_bus_type = { diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 0460d58e3941..5a017c62c752 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -260,7 +260,7 @@ static void disable_wq(struct idxd_wq *wq) dev_info(dev, "wq %s disabled\n", dev_name(&wq->conf_dev)); } -static int idxd_config_bus_remove(struct device *dev) +static void idxd_config_bus_remove(struct device *dev) { int rc; @@ -305,8 +305,6 @@ static int idxd_config_bus_remove(struct device *dev) dev_info(dev, "Device %s disabled\n", dev_name(dev)); } - - return 0; } static void idxd_config_bus_shutdown(struct device *dev) diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 68216988391f..90ed8fdaba75 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -187,14 +187,12 @@ static int fw_unit_probe(struct device *dev) return driver->probe(fw_unit(dev), unit_match(dev, dev->driver)); } -static int fw_unit_remove(struct device *dev) +static void fw_unit_remove(struct device *dev) { struct fw_driver *driver = container_of(dev->driver, struct fw_driver, driver); driver->remove(fw_unit(dev)); - - return 0; } static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 6c7e24935eca..f6fe723ab869 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -111,15 +111,13 @@ static int scmi_dev_probe(struct device *dev) return scmi_drv->probe(scmi_dev); } -static int scmi_dev_remove(struct device *dev) +static void scmi_dev_remove(struct device *dev) { struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver); struct scmi_device *scmi_dev = to_scmi_dev(dev); if (scmi_drv->remove) scmi_drv->remove(scmi_dev); - - return 0; } static struct bus_type scmi_bus_type = { diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c index dc83ea118c67..c52bcaa9def6 100644 --- a/drivers/firmware/google/coreboot_table.c +++ b/drivers/firmware/google/coreboot_table.c @@ -44,15 +44,13 @@ static int coreboot_bus_probe(struct device *dev) return ret; } -static int coreboot_bus_remove(struct device *dev) +static void coreboot_bus_remove(struct device *dev) { struct coreboot_device *device = CB_DEV(dev); struct coreboot_driver *driver = CB_DRV(dev->driver); if (driver->remove) driver->remove(device); - - return 0; } static struct bus_type coreboot_bus_type = { diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 511b20ff35a3..1ae6779a0dd6 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -284,15 +284,13 @@ static int dfl_bus_probe(struct device *dev) return ddrv->probe(ddev); } -static int dfl_bus_remove(struct device *dev) +static void dfl_bus_remove(struct device *dev) { struct dfl_driver *ddrv = to_dfl_drv(dev->driver); struct dfl_device *ddev = to_dfl_dev(dev); if (ddrv->remove) ddrv->remove(ddev); - - return 0; } static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 7db332139f7d..dbed2524fd47 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2302,7 +2302,7 @@ end: return ret; } -static int hid_device_remove(struct device *dev) +static void hid_device_remove(struct device *dev) { struct hid_device *hdev = to_hid_device(dev); struct hid_driver *hdrv; @@ -2322,8 +2322,6 @@ static int hid_device_remove(struct device *dev) if (!hdev->io_started) up(&hdev->driver_input_lock); - - return 0; } static ssize_t modalias_show(struct device *dev, struct device_attribute *a, diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index f0802b047ed8..8a51bd9cd093 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -255,7 +255,7 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv) * * Return: Return value from driver remove() call. */ -static int ishtp_cl_device_remove(struct device *dev) +static void ishtp_cl_device_remove(struct device *dev) { struct ishtp_cl_device *device = to_ishtp_cl_device(dev); struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver); @@ -267,8 +267,6 @@ static int ishtp_cl_device_remove(struct device *dev) if (driver->remove) driver->remove(device); - - return 0; } /** diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 57bbbaa4e8f7..392c1ac4f819 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -922,7 +922,7 @@ static int vmbus_probe(struct device *child_device) /* * vmbus_remove - Remove a vmbus device */ -static int vmbus_remove(struct device *child_device) +static void vmbus_remove(struct device *child_device) { struct hv_driver *drv; struct hv_device *dev = device_to_hv_device(child_device); @@ -932,11 +932,8 @@ static int vmbus_remove(struct device *child_device) if (drv->remove) drv->remove(dev); } - - return 0; } - /* * vmbus_shutdown - Shutdown a vmbus device */ diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 66eed2dff818..7e753a75d23b 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -95,7 +95,7 @@ out_pm: static void intel_th_device_remove(struct intel_th_device *thdev); -static int intel_th_remove(struct device *dev) +static void intel_th_remove(struct device *dev) { struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver); struct intel_th_device *thdev = to_intel_th_device(dev); @@ -164,8 +164,6 @@ static int intel_th_remove(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - - return 0; } static struct bus_type intel_th_bus = { diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 84f12bf90644..54964fbe3f03 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -601,7 +601,7 @@ put_sync_adapter: return status; } -static int i2c_device_remove(struct device *dev) +static void i2c_device_remove(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct i2c_adapter *adap; @@ -631,9 +631,6 @@ static int i2c_device_remove(struct device *dev) client->irq = 0; if (client->flags & I2C_CLIENT_HOST_NOTIFY) pm_runtime_put(&client->adapter->dev); - - /* return always 0 because there is WIP to make remove-functions void */ - return 0; } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index e2e12a5585e5..c3b4c677b442 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -322,7 +322,7 @@ static int i3c_device_probe(struct device *dev) return driver->probe(i3cdev); } -static int i3c_device_remove(struct device *dev) +static void i3c_device_remove(struct device *dev) { struct i3c_device *i3cdev = dev_to_i3cdev(dev); struct i3c_driver *driver = drv_to_i3cdrv(dev->driver); @@ -331,8 +331,6 @@ static int i3c_device_remove(struct device *dev) driver->remove(i3cdev); i3c_device_free_ibi(i3cdev); - - return 0; } struct bus_type i3c_bus_type = { diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 61fa7e724172..db58a01b23d3 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -697,13 +697,12 @@ static int gameport_driver_probe(struct device *dev) return gameport->drv ? 0 : -ENODEV; } -static int gameport_driver_remove(struct device *dev) +static void gameport_driver_remove(struct device *dev) { struct gameport *gameport = to_gameport_port(dev); struct gameport_driver *drv = to_gameport_driver(dev->driver); drv->disconnect(gameport); - return 0; } static void gameport_attach_driver(struct gameport_driver *drv) diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 29f491082926..ec117be3d8d8 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -778,12 +778,11 @@ static int serio_driver_probe(struct device *dev) return serio_connect_driver(serio, drv); } -static int serio_driver_remove(struct device *dev) +static void serio_driver_remove(struct device *dev) { struct serio *serio = to_serio_port(dev); serio_disconnect_driver(serio); - return 0; } static void serio_cleanup(struct serio *serio) diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index 7de9605cac4f..b1c3198355e7 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -67,15 +67,13 @@ static int ipack_bus_probe(struct device *device) return drv->ops->probe(dev); } -static int ipack_bus_remove(struct device *device) +static void ipack_bus_remove(struct device *device) { struct ipack_device *dev = to_ipack_dev(device); struct ipack_driver *drv = to_ipack_driver(device->driver); if (drv->ops->remove) drv->ops->remove(dev); - - return 0; } static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env) diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 49af60bdac92..c1fdf2896021 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -88,7 +88,7 @@ static int macio_device_probe(struct device *dev) return error; } -static int macio_device_remove(struct device *dev) +static void macio_device_remove(struct device *dev) { struct macio_dev * macio_dev = to_macio_device(dev); struct macio_driver * drv = to_macio_driver(dev->driver); @@ -96,8 +96,6 @@ static int macio_device_remove(struct device *dev) if (dev->driver && drv->remove) drv->remove(macio_dev); macio_dev_put(macio_dev); - - return 0; } static void macio_device_shutdown(struct device *dev) diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c index 38fbb3b59873..edf4ee6eff25 100644 --- a/drivers/mcb/mcb-core.c +++ b/drivers/mcb/mcb-core.c @@ -77,7 +77,7 @@ static int mcb_probe(struct device *dev) return ret; } -static int mcb_remove(struct device *dev) +static void mcb_remove(struct device *dev) { struct mcb_driver *mdrv = to_mcb_driver(dev->driver); struct mcb_device *mdev = to_mcb_device(dev); @@ -89,8 +89,6 @@ static int mcb_remove(struct device *dev) module_put(carrier_mod); put_device(&mdev->dev); - - return 0; } static void mcb_shutdown(struct device *dev) diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c index b730225ca887..a2b18e2bed1b 100644 --- a/drivers/media/pci/bt8xx/bttv-gpio.c +++ b/drivers/media/pci/bt8xx/bttv-gpio.c @@ -46,14 +46,13 @@ static int bttv_sub_probe(struct device *dev) return sub->probe ? sub->probe(sdev) : -ENODEV; } -static int bttv_sub_remove(struct device *dev) +static void bttv_sub_remove(struct device *dev) { struct bttv_sub_device *sdev = to_bttv_sub_dev(dev); struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver); if (sub->remove) sub->remove(sdev); - return 0; } struct bus_type bttv_sub_bus_type = { diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index bb1065990aeb..660df7d269fa 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -91,7 +91,7 @@ static int memstick_device_probe(struct device *dev) return rc; } -static int memstick_device_remove(struct device *dev) +static void memstick_device_remove(struct device *dev) { struct memstick_dev *card = container_of(dev, struct memstick_dev, dev); @@ -105,7 +105,6 @@ static int memstick_device_remove(struct device *dev) } put_device(dev); - return 0; } #ifdef CONFIG_PM diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index eff9423e90f5..2fa592c37c6f 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c @@ -33,13 +33,12 @@ static int mcp_bus_probe(struct device *dev) return drv->probe(mcp); } -static int mcp_bus_remove(struct device *dev) +static void mcp_bus_remove(struct device *dev) { struct mcp *mcp = to_mcp(dev); struct mcp_driver *drv = to_mcp_driver(dev->driver); drv->remove(mcp); - return 0; } static struct bus_type mcp_bus_type = { diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 935acc6bbf3c..3bf2bb4fd152 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -884,7 +884,7 @@ static int mei_cl_device_probe(struct device *dev) * * Return: 0 on success; < 0 otherwise */ -static int mei_cl_device_remove(struct device *dev) +static void mei_cl_device_remove(struct device *dev) { struct mei_cl_device *cldev = to_mei_cl_device(dev); struct mei_cl_driver *cldrv = to_mei_cl_driver(dev->driver); @@ -896,8 +896,6 @@ static int mei_cl_device_remove(struct device *dev) mei_cl_bus_module_put(cldev); module_put(THIS_MODULE); - - return 0; } static ssize_t name_show(struct device *dev, struct device_attribute *a, diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 667e574a7df2..52656fc87e99 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -87,7 +87,7 @@ static void tifm_dummy_event(struct tifm_dev *sock) return; } -static int tifm_device_remove(struct device *dev) +static void tifm_device_remove(struct device *dev) { struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, @@ -101,7 +101,6 @@ static int tifm_device_remove(struct device *dev) } put_device(dev); - return 0; } #ifdef CONFIG_PM diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 4383c262b3f5..f6b7a9c5bbff 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -140,14 +140,12 @@ static int mmc_bus_probe(struct device *dev) return drv->probe(card); } -static int mmc_bus_remove(struct device *dev) +static void mmc_bus_remove(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); drv->remove(card); - - return 0; } static void mmc_bus_shutdown(struct device *dev) diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 3d709029e07c..fda03b35c14a 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -203,7 +203,7 @@ disable_runtimepm: return ret; } -static int sdio_bus_remove(struct device *dev) +static void sdio_bus_remove(struct device *dev) { struct sdio_driver *drv = to_sdio_driver(dev->driver); struct sdio_func *func = dev_to_sdio_func(dev); @@ -232,8 +232,6 @@ static int sdio_bus_remove(struct device *dev) pm_runtime_put_sync(dev); dev_pm_domain_detach(dev, false); - - return 0; } static const struct dev_pm_ops sdio_bus_pm_ops = { diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c index ccec29970d5b..14b154929533 100644 --- a/drivers/net/netdevsim/bus.c +++ b/drivers/net/netdevsim/bus.c @@ -370,12 +370,11 @@ static int nsim_bus_probe(struct device *dev) return nsim_dev_probe(nsim_bus_dev); } -static int nsim_bus_remove(struct device *dev) +static void nsim_bus_remove(struct device *dev) { struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); nsim_dev_remove(nsim_bus_dev); - return 0; } static int nsim_num_vf(struct device *dev) diff --git a/drivers/ntb/core.c b/drivers/ntb/core.c index f8f75a504a58..27dd93deff6e 100644 --- a/drivers/ntb/core.c +++ b/drivers/ntb/core.c @@ -271,7 +271,7 @@ static int ntb_probe(struct device *dev) return rc; } -static int ntb_remove(struct device *dev) +static void ntb_remove(struct device *dev) { struct ntb_dev *ntb; struct ntb_client *client; @@ -283,8 +283,6 @@ static int ntb_remove(struct device *dev) client->ops.remove(client, ntb); put_device(dev); } - - return 0; } static void ntb_dev_release(struct device *dev) diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 4a02561cfb96..a9b97ebc71ac 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -304,7 +304,7 @@ static int ntb_transport_bus_probe(struct device *dev) return rc; } -static int ntb_transport_bus_remove(struct device *dev) +static void ntb_transport_bus_remove(struct device *dev) { const struct ntb_transport_client *client; @@ -312,8 +312,6 @@ static int ntb_transport_bus_remove(struct device *dev) client->remove(dev); put_device(dev); - - return 0; } static struct bus_type ntb_transport_bus = { diff --git a/drivers/nubus/bus.c b/drivers/nubus/bus.c index ad3d17c42e23..d9d04f27f89b 100644 --- a/drivers/nubus/bus.c +++ b/drivers/nubus/bus.c @@ -29,14 +29,12 @@ static int nubus_device_probe(struct device *dev) return err; } -static int nubus_device_remove(struct device *dev) +static void nubus_device_remove(struct device *dev) { struct nubus_driver *ndrv = to_nubus_driver(dev->driver); - int err = -ENODEV; if (dev->driver && ndrv->remove) - err = ndrv->remove(to_nubus_board(dev)); - return err; + ndrv->remove(to_nubus_board(dev)); } struct bus_type nubus_bus_type = { diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index e6aa87043a95..9dc7f3edd42b 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -108,7 +108,7 @@ static int nvdimm_bus_probe(struct device *dev) return rc; } -static int nvdimm_bus_remove(struct device *dev) +static void nvdimm_bus_remove(struct device *dev) { struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver); struct module *provider = to_bus_provider(dev); @@ -123,7 +123,6 @@ static int nvdimm_bus_remove(struct device *dev) dev_dbg(&nvdimm_bus->dev, "%s.remove(%s)\n", dev->driver->name, dev_name(dev)); module_put(provider); - return 0; } static void nvdimm_bus_shutdown(struct device *dev) diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 4b9ad96bf1b2..502eb79cd551 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -387,7 +387,7 @@ static int pci_epf_device_probe(struct device *dev) return driver->probe(epf); } -static int pci_epf_device_remove(struct device *dev) +static void pci_epf_device_remove(struct device *dev) { struct pci_epf *epf = to_pci_epf(dev); struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver); @@ -395,8 +395,6 @@ static int pci_epf_device_remove(struct device *dev) if (driver->remove) driver->remove(epf); epf->driver = NULL; - - return 0; } static struct bus_type pci_epf_bus_type = { diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 3a72352aa5cf..a0615395500a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -440,7 +440,7 @@ static int pci_device_probe(struct device *dev) return error; } -static int pci_device_remove(struct device *dev) +static void pci_device_remove(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = pci_dev->driver; @@ -476,7 +476,6 @@ static int pci_device_remove(struct device *dev) */ pci_dev_put(pci_dev); - return 0; } static void pci_device_shutdown(struct device *dev) diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index bd81aa64d011..5bd1b80424e7 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -350,7 +350,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le return; } -static int pcmcia_device_remove(struct device *dev) +static void pcmcia_device_remove(struct device *dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; @@ -389,8 +389,6 @@ static int pcmcia_device_remove(struct device *dev) /* references from pcmcia_device_probe */ pcmcia_put_dev(p_dev); module_put(p_drv->owner); - - return 0; } diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c index 0169677c243e..0a40dd9c94ed 100644 --- a/drivers/platform/surface/aggregator/bus.c +++ b/drivers/platform/surface/aggregator/bus.c @@ -316,14 +316,12 @@ static int ssam_bus_probe(struct device *dev) ->probe(to_ssam_device(dev)); } -static int ssam_bus_remove(struct device *dev) +static void ssam_bus_remove(struct device *dev) { struct ssam_device_driver *sdrv = to_ssam_device_driver(dev->driver); if (sdrv->remove) sdrv->remove(to_ssam_device(dev)); - - return 0; } struct bus_type ssam_bus_type = { diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 62e0d56a3332..a76313006bdc 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -980,7 +980,7 @@ probe_failure: return ret; } -static int wmi_dev_remove(struct device *dev) +static void wmi_dev_remove(struct device *dev) { struct wmi_block *wblock = dev_to_wblock(dev); struct wmi_driver *wdriver = @@ -997,8 +997,6 @@ static int wmi_dev_remove(struct device *dev) if (ACPI_FAILURE(wmi_method_enable(wblock, 0))) dev_warn(dev, "failed to disable device\n"); - - return 0; } static struct class wmi_bus_class = { diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index c29d590c5e4f..cc6757dfa3f1 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -123,7 +123,7 @@ fail: return error; } -static int pnp_device_remove(struct device *dev) +static void pnp_device_remove(struct device *dev) { struct pnp_dev *pnp_dev = to_pnp_dev(dev); struct pnp_driver *drv = pnp_dev->driver; @@ -139,7 +139,6 @@ static int pnp_device_remove(struct device *dev) pnp_disable_dev(pnp_dev); pnp_device_detach(pnp_dev); - return 0; } static void pnp_device_shutdown(struct device *dev) diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 72874153972e..a72bb0a40fcf 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -112,7 +112,7 @@ static int rio_device_probe(struct device *dev) * driver, then run the driver remove() method. Then update * the reference count. */ -static int rio_device_remove(struct device *dev) +static void rio_device_remove(struct device *dev) { struct rio_dev *rdev = to_rio_dev(dev); struct rio_driver *rdrv = rdev->driver; @@ -124,8 +124,6 @@ static int rio_device_remove(struct device *dev) } rio_dev_put(rdev); - - return 0; } static void rio_device_shutdown(struct device *dev) diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index c1404d3dae2c..9151836190ce 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -530,14 +530,13 @@ out: return err; } -static int rpmsg_dev_remove(struct device *dev) +static void rpmsg_dev_remove(struct device *dev) { struct rpmsg_device *rpdev = to_rpmsg_device(dev); struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); - int err = 0; if (rpdev->ops->announce_destroy) - err = rpdev->ops->announce_destroy(rpdev); + rpdev->ops->announce_destroy(rpdev); if (rpdrv->remove) rpdrv->remove(rpdev); @@ -546,8 +545,6 @@ static int rpmsg_dev_remove(struct device *dev) if (rpdev->ept) rpmsg_destroy_ept(rpdev->ept); - - return err; } static struct bus_type rpmsg_bus = { diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index a6aeab1ea0ae..382c5b5f8cd3 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -439,15 +439,13 @@ module_exit(cleanup_ccwgroup); /************************** driver stuff ******************************/ -static int ccwgroup_remove(struct device *dev) +static void ccwgroup_remove(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); if (gdrv->remove) gdrv->remove(gdev); - - return 0; } static void ccwgroup_shutdown(struct device *dev) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 092fd1ea5799..ebc321edba51 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1371,7 +1371,7 @@ static int css_probe(struct device *dev) return ret; } -static int css_remove(struct device *dev) +static void css_remove(struct device *dev) { struct subchannel *sch; @@ -1379,8 +1379,6 @@ static int css_remove(struct device *dev) if (sch->driver->remove) sch->driver->remove(sch); sch->driver = NULL; - - return 0; } static void css_shutdown(struct device *dev) diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index cd5d2d4d8e46..adf33b653d87 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1741,7 +1741,7 @@ ccw_device_probe (struct device *dev) return 0; } -static int ccw_device_remove(struct device *dev) +static void ccw_device_remove(struct device *dev) { struct ccw_device *cdev = to_ccwdev(dev); struct ccw_driver *cdrv = cdev->drv; @@ -1775,8 +1775,6 @@ static int ccw_device_remove(struct device *dev) spin_unlock_irq(cdev->ccwlock); io_subchannel_quiesce(sch); __disable_cmf(cdev); - - return 0; } static void ccw_device_shutdown(struct device *dev) diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index b31711307e5a..b6b4589c70bd 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c @@ -28,15 +28,13 @@ static int scmdev_probe(struct device *dev) return scmdrv->probe ? scmdrv->probe(scmdev) : -ENODEV; } -static int scmdev_remove(struct device *dev) +static void scmdev_remove(struct device *dev) { struct scm_device *scmdev = to_scm_dev(dev); struct scm_driver *scmdrv = to_scm_drv(dev->driver); if (scmdrv->remove) scmdrv->remove(scmdev); - - return 0; } static int scmdev_uevent(struct device *dev, struct kobj_uevent_env *env) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 8d3a1d84a757..0992edcaf1af 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -901,7 +901,7 @@ out: return rc; } -static int ap_device_remove(struct device *dev) +static void ap_device_remove(struct device *dev) { struct ap_device *ap_dev = to_ap_dev(dev); struct ap_driver *ap_drv = ap_dev->drv; @@ -926,8 +926,6 @@ static int ap_device_remove(struct device *dev) ap_dev->drv = NULL; put_device(dev); - - return 0; } struct ap_queue *ap_get_qdev(ap_qid_t qid) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 5b3a20a140f9..58f69366bdcc 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7674,7 +7674,7 @@ static int sdebug_driver_probe(struct device *dev) return error; } -static int sdebug_driver_remove(struct device *dev) +static void sdebug_driver_remove(struct device *dev) { struct sdebug_host_info *sdbg_host; struct sdebug_dev_info *sdbg_devinfo, *tmp; @@ -7691,7 +7691,6 @@ static int sdebug_driver_remove(struct device *dev) } scsi_host_put(sdbg_host->shost); - return 0; } static int pseudo_lld_bus_match(struct device *dev, diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c index 348836b90605..c0ab904c76ec 100644 --- a/drivers/sh/superhyway/superhyway.c +++ b/drivers/sh/superhyway/superhyway.c @@ -150,17 +150,13 @@ static int superhyway_device_probe(struct device *dev) return -ENODEV; } -static int superhyway_device_remove(struct device *dev) +static void superhyway_device_remove(struct device *dev) { struct superhyway_device *shyway_dev = to_superhyway_device(dev); struct superhyway_driver *shyway_drv = to_superhyway_driver(dev->driver); - if (shyway_drv && shyway_drv->remove) { + if (shyway_drv && shyway_drv->remove) shyway_drv->remove(shyway_dev); - return 0; - } - - return -ENODEV; } /** diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c index 1794ff0106bc..7c4f32d76966 100644 --- a/drivers/siox/siox-core.c +++ b/drivers/siox/siox-core.c @@ -520,7 +520,7 @@ static int siox_probe(struct device *dev) return sdriver->probe(sdevice); } -static int siox_remove(struct device *dev) +static void siox_remove(struct device *dev) { struct siox_driver *sdriver = container_of(dev->driver, struct siox_driver, driver); @@ -528,8 +528,6 @@ static int siox_remove(struct device *dev) if (sdriver->remove) sdriver->remove(sdevice); - - return 0; } static void siox_shutdown(struct device *dev) diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c index 1d2bc181da05..78480e332ab8 100644 --- a/drivers/slimbus/core.c +++ b/drivers/slimbus/core.c @@ -81,7 +81,7 @@ static int slim_device_probe(struct device *dev) return ret; } -static int slim_device_remove(struct device *dev) +static void slim_device_remove(struct device *dev) { struct slim_device *sbdev = to_slim_device(dev); struct slim_driver *sbdrv; @@ -91,8 +91,6 @@ static int slim_device_remove(struct device *dev) if (sbdrv->remove) sbdrv->remove(sbdev); } - - return 0; } static int slim_device_uevent(struct device *dev, struct kobj_uevent_env *env) diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index 7abfc8c4fdc7..475a57b435b2 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -217,7 +217,7 @@ static int apr_device_probe(struct device *dev) return adrv->probe(adev); } -static int apr_device_remove(struct device *dev) +static void apr_device_remove(struct device *dev) { struct apr_device *adev = to_apr_device(dev); struct apr_driver *adrv; @@ -231,8 +231,6 @@ static int apr_device_remove(struct device *dev) idr_remove(&apr->svcs_idr, adev->svc_id); spin_unlock(&apr->svcs_lock); } - - return 0; } static int apr_uevent(struct device *dev, struct kobj_uevent_env *env) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index c99181165321..ad2b558dc9cb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -405,7 +405,7 @@ static int spi_probe(struct device *dev) return ret; } -static int spi_remove(struct device *dev) +static void spi_remove(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); @@ -420,8 +420,6 @@ static int spi_remove(struct device *dev) } dev_pm_domain_detach(dev, true); - - return 0; } static void spi_shutdown(struct device *dev) diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 51f5aeb65b3b..b37ead9e2fad 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -345,7 +345,7 @@ fail_probe: return err; } -static int spmi_drv_remove(struct device *dev) +static void spmi_drv_remove(struct device *dev) { const struct spmi_driver *sdrv = to_spmi_driver(dev->driver); @@ -356,7 +356,6 @@ static int spmi_drv_remove(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_put_noidle(dev); - return 0; } static void spmi_drv_shutdown(struct device *dev) diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 3a29b5570f9f..8a93c83cb6f8 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -283,7 +283,7 @@ static void ssb_device_shutdown(struct device *dev) ssb_drv->shutdown(ssb_dev); } -static int ssb_device_remove(struct device *dev) +static void ssb_device_remove(struct device *dev) { struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver); @@ -291,8 +291,6 @@ static int ssb_device_remove(struct device *dev) if (ssb_drv && ssb_drv->remove) ssb_drv->remove(ssb_dev); ssb_device_put(ssb_dev); - - return 0; } static int ssb_device_probe(struct device *dev) diff --git a/drivers/staging/fieldbus/anybuss/host.c b/drivers/staging/fieldbus/anybuss/host.c index 0f730efe9a6d..8a75f6642c78 100644 --- a/drivers/staging/fieldbus/anybuss/host.c +++ b/drivers/staging/fieldbus/anybuss/host.c @@ -1186,15 +1186,13 @@ static int anybus_bus_probe(struct device *dev) return adrv->probe(adev); } -static int anybus_bus_remove(struct device *dev) +static void anybus_bus_remove(struct device *dev) { struct anybuss_client_driver *adrv = to_anybuss_client_driver(dev->driver); if (adrv->remove) adrv->remove(to_anybuss_client(dev)); - - return 0; } static struct bus_type anybus_bus = { diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index 13d319860da5..5a5c17a4519b 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -169,7 +169,7 @@ static int gbphy_dev_probe(struct device *dev) return ret; } -static int gbphy_dev_remove(struct device *dev) +static void gbphy_dev_remove(struct device *dev) { struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver); struct gbphy_device *gbphy_dev = to_gbphy_dev(dev); @@ -180,8 +180,6 @@ static int gbphy_dev_remove(struct device *dev) pm_runtime_set_suspended(dev); pm_runtime_put_noidle(dev); pm_runtime_dont_use_autosuspend(dev); - - return 0; } static struct bus_type gbphy_bus_type = { diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 6d0b0e67e79e..cbb2118fb35e 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -81,7 +81,7 @@ static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host) } static int tcm_loop_driver_probe(struct device *); -static int tcm_loop_driver_remove(struct device *); +static void tcm_loop_driver_remove(struct device *); static int pseudo_lld_bus_match(struct device *dev, struct device_driver *dev_driver) @@ -363,7 +363,7 @@ static int tcm_loop_driver_probe(struct device *dev) return 0; } -static int tcm_loop_driver_remove(struct device *dev) +static void tcm_loop_driver_remove(struct device *dev) { struct tcm_loop_hba *tl_hba; struct Scsi_Host *sh; @@ -373,7 +373,6 @@ static int tcm_loop_driver_remove(struct device *dev) scsi_remove_host(sh); scsi_host_put(sh); - return 0; } static void tcm_loop_release_adapter(struct device *dev) diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index a062befcb3b2..7018d959f775 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -86,7 +86,7 @@ static int tb_service_probe(struct device *dev) return driver->probe(svc, id); } -static int tb_service_remove(struct device *dev) +static void tb_service_remove(struct device *dev) { struct tb_service *svc = tb_to_service(dev); struct tb_service_driver *driver; @@ -94,8 +94,6 @@ static int tb_service_remove(struct device *dev) driver = container_of(dev->driver, struct tb_service_driver, driver); if (driver->remove) driver->remove(svc); - - return 0; } static void tb_service_shutdown(struct device *dev) diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 9cdfcfe07e87..92498961fd92 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -421,15 +421,13 @@ static int serdev_drv_probe(struct device *dev) return ret; } -static int serdev_drv_remove(struct device *dev) +static void serdev_drv_remove(struct device *dev) { const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver); if (sdrv->remove) sdrv->remove(to_serdev_device(dev)); dev_pm_domain_detach(dev, true); - - return 0; } static struct bus_type serdev_bus_type = { diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 7e13b74e60e5..4169cf40a03b 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -78,14 +78,12 @@ static int ulpi_probe(struct device *dev) return drv->probe(to_ulpi_dev(dev)); } -static int ulpi_remove(struct device *dev) +static void ulpi_remove(struct device *dev) { struct ulpi_driver *drv = to_ulpi_driver(dev->driver); if (drv->remove) drv->remove(to_ulpi_dev(dev)); - - return 0; } static struct bus_type ulpi_bus = { diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 7133818a58b9..9e38142acd38 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -74,7 +74,7 @@ err_autopm_put: return retval; } -static int usb_serial_device_remove(struct device *dev) +static void usb_serial_device_remove(struct device *dev) { struct usb_serial_port *port = to_usb_serial_port(dev); struct usb_serial_driver *driver; @@ -101,8 +101,6 @@ static int usb_serial_device_remove(struct device *dev) if (!autopm_err) usb_autopm_put_interface(port->serial->interface); - - return 0; } static ssize_t new_id_store(struct device_driver *driver, diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index 7f3c9a8e2bf0..78e0e78954f2 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -382,7 +382,7 @@ static int typec_probe(struct device *dev) return ret; } -static int typec_remove(struct device *dev) +static void typec_remove(struct device *dev) { struct typec_altmode_driver *drv = to_altmode_driver(dev->driver); struct typec_altmode *adev = to_typec_altmode(dev); @@ -400,8 +400,6 @@ static int typec_remove(struct device *dev) adev->desc = NULL; adev->ops = NULL; - - return 0; } struct bus_type typec_bus = { diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index bb3f1d1f0422..3fc4525fc05c 100644 --- a/drivers/vdpa/vdpa.c +++ b/drivers/vdpa/vdpa.c @@ -34,15 +34,13 @@ static int vdpa_dev_probe(struct device *d) return ret; } -static int vdpa_dev_remove(struct device *d) +static void vdpa_dev_remove(struct device *d) { struct vdpa_device *vdev = dev_to_vdpa(d); struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver); if (drv && drv->remove) drv->remove(vdev); - - return 0; } static struct bus_type vdpa_bus = { diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c index c368ec824e2b..e2cb1ff56f6c 100644 --- a/drivers/vfio/mdev/mdev_driver.c +++ b/drivers/vfio/mdev/mdev_driver.c @@ -57,7 +57,7 @@ static int mdev_probe(struct device *dev) return ret; } -static int mdev_remove(struct device *dev) +static void mdev_remove(struct device *dev) { struct mdev_driver *drv = container_of(dev->driver, struct mdev_driver, driver); @@ -67,8 +67,6 @@ static int mdev_remove(struct device *dev) drv->remove(mdev); mdev_detach_iommu(mdev); - - return 0; } static int mdev_match(struct device *dev, struct device_driver *drv) diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 4b15c00c0a0a..2a6055c0d4d3 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -278,7 +278,7 @@ err: } -static int virtio_dev_remove(struct device *_d) +static void virtio_dev_remove(struct device *_d) { struct virtio_device *dev = dev_to_virtio(_d); struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); @@ -292,7 +292,6 @@ static int virtio_dev_remove(struct device *_d) /* Acknowledge the device's existence again. */ virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); - return 0; } static struct bus_type virtio_bus = { diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c index e966981c0215..4af6615808cc 100644 --- a/drivers/vlynq/vlynq.c +++ b/drivers/vlynq/vlynq.c @@ -342,14 +342,12 @@ static int vlynq_device_probe(struct device *dev) return result; } -static int vlynq_device_remove(struct device *dev) +static void vlynq_device_remove(struct device *dev) { struct vlynq_driver *drv = to_vlynq_driver(dev->driver); if (drv->remove) drv->remove(to_vlynq_device(dev)); - - return 0; } int __vlynq_register_driver(struct vlynq_driver *driver, struct module *owner) diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c index 1b15afea28ee..8dba20186be3 100644 --- a/drivers/vme/vme.c +++ b/drivers/vme/vme.c @@ -1990,7 +1990,7 @@ static int vme_bus_probe(struct device *dev) return -ENODEV; } -static int vme_bus_remove(struct device *dev) +static void vme_bus_remove(struct device *dev) { struct vme_driver *driver; struct vme_dev *vdev = dev_to_vme_dev(dev); @@ -1998,8 +1998,6 @@ static int vme_bus_remove(struct device *dev) driver = dev->platform_data; if (driver->remove) driver->remove(vdev); - - return 0; } struct bus_type vme_bus_type = { diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h index 2a93b7c9c159..2754bdfadcb8 100644 --- a/drivers/xen/xenbus/xenbus.h +++ b/drivers/xen/xenbus/xenbus.h @@ -106,7 +106,7 @@ void xs_request_exit(struct xb_req_data *req); int xenbus_match(struct device *_dev, struct device_driver *_drv); int xenbus_dev_probe(struct device *_dev); -int xenbus_dev_remove(struct device *_dev); +void xenbus_dev_remove(struct device *_dev); int xenbus_register_driver_common(struct xenbus_driver *drv, struct xen_bus_type *bus, struct module *owner, diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 33d09b3f6211..bd003ca8acbe 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -325,7 +325,7 @@ fail: } EXPORT_SYMBOL_GPL(xenbus_dev_probe); -int xenbus_dev_remove(struct device *_dev) +void xenbus_dev_remove(struct device *_dev) { struct xenbus_device *dev = to_xenbus_device(_dev); struct xenbus_driver *drv = to_xenbus_driver(_dev->driver); @@ -355,8 +355,6 @@ int xenbus_dev_remove(struct device *_dev) if (!drv->allow_rebind || xenbus_read_driver_state(dev->nodename) == XenbusStateClosing) xenbus_switch_state(dev, XenbusStateClosed); - - return 0; } EXPORT_SYMBOL_GPL(xenbus_dev_remove); diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c index 0dd7cbcec2b0..c18524bb8b2a 100644 --- a/drivers/zorro/zorro-driver.c +++ b/drivers/zorro/zorro-driver.c @@ -62,7 +62,7 @@ static int zorro_device_probe(struct device *dev) } -static int zorro_device_remove(struct device *dev) +static void zorro_device_remove(struct device *dev) { struct zorro_dev *z = to_zorro_dev(dev); struct zorro_driver *drv = to_zorro_driver(dev->driver); @@ -72,7 +72,6 @@ static int zorro_device_remove(struct device *dev) drv->remove(z); z->driver = NULL; } - return 0; } diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index 1ea5e1d1545b..062777a45a74 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -91,7 +91,7 @@ struct bus_type { int (*uevent)(struct device *dev, struct kobj_uevent_env *env); int (*probe)(struct device *dev); void (*sync_state)(struct device *dev); - int (*remove)(struct device *dev); + void (*remove)(struct device *dev); void (*shutdown)(struct device *dev); int (*online)(struct device *dev); diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c index 6ddf646cda65..0d31a6d71468 100644 --- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -514,7 +514,7 @@ static int ac97_bus_probe(struct device *dev) return ret; } -static int ac97_bus_remove(struct device *dev) +static void ac97_bus_remove(struct device *dev) { struct ac97_codec_device *adev = to_ac97_device(dev); struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver); @@ -522,7 +522,7 @@ static int ac97_bus_remove(struct device *dev) ret = pm_runtime_resume_and_get(dev); if (ret < 0) - return ret; + return; ret = adrv->remove(adev); pm_runtime_put_noidle(dev); @@ -530,8 +530,6 @@ static int ac97_bus_remove(struct device *dev) ac97_put_disable_clk(adev); pm_runtime_disable(dev); - - return ret; } static struct bus_type ac97_bus_type = { diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c index 002fb5bf220b..c9579d97fbab 100644 --- a/sound/aoa/soundbus/core.c +++ b/sound/aoa/soundbus/core.c @@ -104,7 +104,7 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) return retval; } -static int soundbus_device_remove(struct device *dev) +static void soundbus_device_remove(struct device *dev) { struct soundbus_dev * soundbus_dev = to_soundbus_device(dev); struct soundbus_driver * drv = to_soundbus_driver(dev->driver); @@ -112,8 +112,6 @@ static int soundbus_device_remove(struct device *dev) if (dev->driver && drv->remove) drv->remove(soundbus_dev); soundbus_dev_put(soundbus_dev); - - return 0; } static void soundbus_device_shutdown(struct device *dev) -- cgit v1.2.1 From 16b0dd40922995bb13f140b025bb760b6c5224b0 Mon Sep 17 00:00:00 2001 From: Jinchao Wang Date: Sat, 26 Jun 2021 17:46:06 +0800 Subject: driver: base: Replace symbolic permissions with octal permissions Resolve following checkpatch issue, Replace symbolic permissions with octal permissions Signed-off-by: Jinchao Wang Link: https://lore.kernel.org/r/20210626094606.53152-1-wjc@cdjrlc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 6 +++--- drivers/base/power/wakeup.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 1f6b4bd61056..bdc98c5713d5 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -195,7 +195,7 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf, bus_put(bus); return err; } -static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, S_IWUSR, NULL, unbind_store); +static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store); /* * Manually attach a device to a driver. @@ -221,7 +221,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, bus_put(bus); return err; } -static DRIVER_ATTR_IGNORE_LOCKDEP(bind, S_IWUSR, NULL, bind_store); +static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store); static ssize_t drivers_autoprobe_show(struct bus_type *bus, char *buf) { @@ -767,7 +767,7 @@ static ssize_t bus_uevent_store(struct bus_type *bus, * DEVICE_ATTR_WO(uevent), which would cause a clash with the with the store * function name. */ -static struct bus_attribute bus_attr_uevent = __ATTR(uevent, S_IWUSR, NULL, +static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL, bus_uevent_store); /** diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index f0b37c188514..99bda0da23a8 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -1180,7 +1180,7 @@ static const struct file_operations wakeup_sources_stats_fops = { static int __init wakeup_sources_debugfs_init(void) { - debugfs_create_file("wakeup_sources", S_IRUGO, NULL, NULL, + debugfs_create_file("wakeup_sources", 0444, NULL, NULL, &wakeup_sources_stats_fops); return 0; } -- cgit v1.2.1 From fe968ca2cac91888310b143a483123c84906e3fc Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 7 Jul 2021 21:18:27 -0600 Subject: selftests: firmware: Fix ignored return val of asprintf() warn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following ingonred return val of asprintf() warn during build: cc -Wall -O2 fw_namespace.c -o ../tools/testing/selftests/firmware/fw_namespace fw_namespace.c: In function ‘main’: fw_namespace.c:132:2: warning: ignoring return value of ‘asprintf’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 132 | asprintf(&fw_path, "/lib/firmware/%s", fw_name); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Shuah Khan Link: https://lore.kernel.org/r/20210708031827.51293-1-skhan@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- tools/testing/selftests/firmware/fw_namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/firmware/fw_namespace.c b/tools/testing/selftests/firmware/fw_namespace.c index 0e393cb5f42d..4c6f0cd83c5b 100644 --- a/tools/testing/selftests/firmware/fw_namespace.c +++ b/tools/testing/selftests/firmware/fw_namespace.c @@ -129,7 +129,8 @@ int main(int argc, char **argv) die("mounting tmpfs to /lib/firmware failed\n"); sys_path = argv[1]; - asprintf(&fw_path, "/lib/firmware/%s", fw_name); + if (asprintf(&fw_path, "/lib/firmware/%s", fw_name) < 0) + die("error: failed to build full fw_path\n"); setup_fw(fw_path); -- cgit v1.2.1 From d3ce197903279c5497d4fa9cc97b519400dc4a44 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 14 Jul 2021 17:15:59 +0200 Subject: sysfs: Use local reference in compat_only_sysfs_link_entry_to_kobj() As we have just obtained target_kobj->sd into a local variable, and incremented the object's reference count, it is better to use the local variable instead of the original reference. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20210714151559.2532572-1-geert@linux-m68k.org Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 64e6a6698935..f29d62004527 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -446,7 +446,7 @@ int compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj, if (!target) return -ENOENT; - entry = kernfs_find_and_get(target_kobj->sd, target_name); + entry = kernfs_find_and_get(target, target_name); if (!entry) { kernfs_put(target); return -ENOENT; -- cgit v1.2.1 From 3ecc8cb7c092b2f50e21d2aaaae35b8221ee7214 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Mon, 19 Jul 2021 14:45:31 +0800 Subject: firmware: fix theoretical UAF race with firmware cache and resume This race was discovered when I carefully analyzed the code to locate another firmware-related UAF issue. It can be triggered only when the firmware load operation is executed during suspend. This possibility is almost impossible because there are few firmware load and suspend actions in the actual environment. CPU0 CPU1 __device_uncache_fw_images(): assign_fw(): fw_cache_piggyback_on_request() <----- P0 spin_lock(&fwc->name_lock); ... list_del(&fce->list); spin_unlock(&fwc->name_lock); uncache_firmware(fce->name); <----- P1 kref_get(&fw_priv->ref); If CPU1 is interrupted at position P0, the new 'fce' has been added to the list fwc->fw_names by the fw_cache_piggyback_on_request(). In this case, CPU0 executes __device_uncache_fw_images() and will be able to see it when it traverses list fwc->fw_names. Before CPU1 executes kref_get() at P1, if CPU0 further executes uncache_firmware(), the count of fw_priv->ref may decrease to 0, causing fw_priv to be released in advance. Move kref_get() to the lock protection range of fwc->name_lock to fix it. Fixes: ac39b3ea73aa ("firmware loader: let caching firmware piggyback on loading firmware") Acked-by: Luis Chamberlain Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210719064531.3733-2-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/main.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 4fdb8219cd08..2f267b8d2fd9 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -165,7 +165,7 @@ static inline int fw_state_wait(struct fw_priv *fw_priv) return __fw_state_wait_common(fw_priv, MAX_SCHEDULE_TIMEOUT); } -static int fw_cache_piggyback_on_request(const char *name); +static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv); static struct fw_priv *__allocate_fw_priv(const char *fw_name, struct firmware_cache *fwc, @@ -707,10 +707,8 @@ int assign_fw(struct firmware *fw, struct device *device) * on request firmware. */ if (!(fw_priv->opt_flags & FW_OPT_NOCACHE) && - fw_priv->fwc->state == FW_LOADER_START_CACHE) { - if (fw_cache_piggyback_on_request(fw_priv->fw_name)) - kref_get(&fw_priv->ref); - } + fw_priv->fwc->state == FW_LOADER_START_CACHE) + fw_cache_piggyback_on_request(fw_priv); /* pass the pages buffer to driver at the last minute */ fw_set_page_data(fw_priv, fw); @@ -1257,11 +1255,11 @@ static int __fw_entry_found(const char *name) return 0; } -static int fw_cache_piggyback_on_request(const char *name) +static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv) { - struct firmware_cache *fwc = &fw_cache; + const char *name = fw_priv->fw_name; + struct firmware_cache *fwc = fw_priv->fwc; struct fw_cache_entry *fce; - int ret = 0; spin_lock(&fwc->name_lock); if (__fw_entry_found(name)) @@ -1269,13 +1267,12 @@ static int fw_cache_piggyback_on_request(const char *name) fce = alloc_fw_cache_entry(name); if (fce) { - ret = 1; list_add(&fce->list, &fwc->fw_names); + kref_get(&fw_priv->ref); pr_debug("%s: fw: %s\n", __func__, name); } found: spin_unlock(&fwc->name_lock); - return ret; } static void free_fw_cache_entry(struct fw_cache_entry *fce) @@ -1506,9 +1503,8 @@ static inline void unregister_fw_pm_ops(void) unregister_pm_notifier(&fw_cache.pm_notify); } #else -static int fw_cache_piggyback_on_request(const char *name) +static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv) { - return 0; } static inline int register_fw_pm_ops(void) { -- cgit v1.2.1 From f04948dea236b000da09c466a7ec931ecd8d7867 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Wed, 7 Jul 2021 15:43:01 +0800 Subject: driver core: Fix error return code in really_probe() In the case of error handling, the error code returned by the subfunction should be propagated instead of 0. Fixes: 1901fb2604fb ("Driver core: fix "driver" symlink timing") Fixes: 23b6904442d0 ("driver core: add dev_groups to all drivers") Fixes: 8fd456ec0cf0 ("driver core: Add state_synced sysfs file for devices that support it") Reported-by: Hulk Robot Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210707074301.2722-1-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index daeb9b5763ae..2b8cdb78384c 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -580,7 +580,8 @@ re_probe: goto probe_failed; } - if (driver_sysfs_add(dev)) { + ret = driver_sysfs_add(dev); + if (ret) { pr_err("%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); goto probe_failed; @@ -602,15 +603,18 @@ re_probe: goto probe_failed; } - if (device_add_groups(dev, drv->dev_groups)) { + ret = device_add_groups(dev, drv->dev_groups); + if (ret) { dev_err(dev, "device_add_groups() failed\n"); goto dev_groups_failed; } - if (dev_has_sync_state(dev) && - device_create_file(dev, &dev_attr_state_synced)) { - dev_err(dev, "state_synced sysfs add failed\n"); - goto dev_sysfs_state_synced_failed; + if (dev_has_sync_state(dev)) { + ret = device_create_file(dev, &dev_attr_state_synced); + if (ret) { + dev_err(dev, "state_synced sysfs add failed\n"); + goto dev_sysfs_state_synced_failed; + } } if (test_remove) { -- cgit v1.2.1 From e022eac85ecd2140a0829970d923d984356185eb Mon Sep 17 00:00:00 2001 From: Xiongfeng Wang Date: Wed, 14 Jul 2021 09:32:55 +0800 Subject: cacheinfo: clear cache_leaves(cpu) in free_cache_attributes() On ARM64, when PPTT(Processor Properties Topology Table) is not implemented in ACPI boot, we will goto 'free_ci' with the following print: Unable to detect cache hierarchy for CPU 0 But some other codes may still use 'num_leaves' to iterate through the 'info_list', such as get_cpu_cacheinfo_id(). If 'info_list' is NULL , it would crash. So clear 'num_leaves' in free_cache_attributes(). Reviewed-by: Sudeep Holla Signed-off-by: Xiongfeng Wang Link: https://lore.kernel.org/r/1626226375-58730-1-git-send-email-wangxiongfeng2@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cacheinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index bfc095956dd1..dad296229161 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -297,6 +297,7 @@ static void free_cache_attributes(unsigned int cpu) kfree(per_cpu_cacheinfo(cpu)); per_cpu_cacheinfo(cpu) = NULL; + cache_leaves(cpu) = 0; } int __weak init_cache_level(unsigned int cpu) -- cgit v1.2.1 From e7deeb9d79d8691f1e6c4c6707471ec3d7b9886b Mon Sep 17 00:00:00 2001 From: Jinchao Wang Date: Tue, 29 Jun 2021 01:19:07 +0800 Subject: driver: base: Prefer unsigned int to bare use of unsigned Fix checkpatch warnings: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: Jinchao Wang Link: https://lore.kernel.org/r/20210628171907.63646-2-wjc@cdjrlc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cpu.c | 4 ++-- drivers/base/map.c | 12 ++++++------ drivers/base/node.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 5ef14db97904..5fc258073bc7 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -388,7 +388,7 @@ int register_cpu(struct cpu *cpu, int num) return 0; } -struct device *get_cpu_device(unsigned cpu) +struct device *get_cpu_device(unsigned int cpu) { if (cpu < nr_cpu_ids && cpu_possible(cpu)) return per_cpu(cpu_sys_devices, cpu); @@ -484,7 +484,7 @@ static const struct attribute_group *cpu_root_attr_groups[] = { NULL, }; -bool cpu_is_hotpluggable(unsigned cpu) +bool cpu_is_hotpluggable(unsigned int cpu) { struct device *dev = get_cpu_device(cpu); return dev && container_of(dev, struct cpu, dev)->hotpluggable; diff --git a/drivers/base/map.c b/drivers/base/map.c index 5650ab2b247a..83aeb09ca161 100644 --- a/drivers/base/map.c +++ b/drivers/base/map.c @@ -33,9 +33,9 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, struct module *module, kobj_probe_t *probe, int (*lock)(dev_t, void *), void *data) { - unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; - unsigned index = MAJOR(dev); - unsigned i; + unsigned int n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; + unsigned int index = MAJOR(dev); + unsigned int i; struct probe *p; if (n > 255) @@ -67,9 +67,9 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) { - unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; - unsigned index = MAJOR(dev); - unsigned i; + unsigned int n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; + unsigned int index = MAJOR(dev); + unsigned int i; struct probe *found = NULL; if (n > 255) diff --git a/drivers/base/node.c b/drivers/base/node.c index 4a4ae868ad9f..2bc9089f3e78 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -75,7 +75,7 @@ static DEVICE_ATTR_RO(cpulist); struct node_access_nodes { struct device dev; struct list_head list_node; - unsigned access; + unsigned int access; #ifdef CONFIG_HMEM_REPORTING struct node_hmem_attrs hmem_attrs; #endif @@ -122,7 +122,7 @@ static void node_access_release(struct device *dev) } static struct node_access_nodes *node_init_node_access(struct node *node, - unsigned access) + unsigned int access) { struct node_access_nodes *access_node; struct device *dev; @@ -187,7 +187,7 @@ static struct attribute *access_attrs[] = { * @access: The access class the for the given attributes */ void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, - unsigned access) + unsigned int access) { struct node_access_nodes *c; struct node *node; @@ -711,7 +711,7 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid) */ int register_memory_node_under_compute_node(unsigned int mem_nid, unsigned int cpu_nid, - unsigned access) + unsigned int access) { struct node *init_node, *targ_node; struct node_access_nodes *initiator, *target; -- cgit v1.2.1 From 895adbec302e92086359e6fd92611ac3be6d92c3 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Fri, 16 Jul 2021 17:28:18 +0800 Subject: kernfs: add a revision to identify directory node changes Add a revision counter to kernfs directory nodes so it can be used to detect if a directory node has changed during negative dentry revalidation. There's an assumption that sizeof(unsigned long) <= sizeof(pointer) on all architectures and as far as I know that assumption holds. So adding a revision counter to the struct kernfs_elem_dir variant of the kernfs_node type union won't increase the size of the kernfs_node struct. This is because struct kernfs_elem_dir is at least sizeof(pointer) smaller than the largest union variant. It's tempting to make the revision counter a u64 but that would increase the size of kernfs_node on archs where sizeof(pointer) is smaller than the revision counter. Reviewed-by: Miklos Szeredi Signed-off-by: Ian Kent Link: https://lore.kernel.org/r/162642769895.63632.8356662784964509867.stgit@web.messagingengine.com Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 2 ++ fs/kernfs/kernfs-internal.h | 19 +++++++++++++++++++ include/linux/kernfs.h | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 33166ec90a11..b3d1bc0f317d 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -372,6 +372,7 @@ static int kernfs_link_sibling(struct kernfs_node *kn) /* successfully added, account subdir number */ if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs++; + kernfs_inc_rev(kn->parent); return 0; } @@ -394,6 +395,7 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn) if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; + kernfs_inc_rev(kn->parent); rb_erase(&kn->rb, &kn->parent->dir.children); RB_CLEAR_NODE(&kn->rb); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index ccc3b44f6306..c2ae58f3b202 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -81,6 +81,25 @@ static inline struct kernfs_node *kernfs_dentry_node(struct dentry *dentry) return d_inode(dentry)->i_private; } +static inline void kernfs_set_rev(struct kernfs_node *parent, + struct dentry *dentry) +{ + dentry->d_time = parent->dir.rev; +} + +static inline void kernfs_inc_rev(struct kernfs_node *parent) +{ + parent->dir.rev++; +} + +static inline bool kernfs_dir_changed(struct kernfs_node *parent, + struct dentry *dentry) +{ + if (parent->dir.rev != dentry->d_time) + return true; + return false; +} + extern const struct super_operations kernfs_sops; extern struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 9e8ca8743c26..d68b4ad09573 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -98,6 +98,11 @@ struct kernfs_elem_dir { * better directly in kernfs_node but is here to save space. */ struct kernfs_root *root; + /* + * Monotonic revision counter, used to identify if a directory + * node has changed during negative dentry revalidation. + */ + unsigned long rev; }; struct kernfs_elem_symlink { -- cgit v1.2.1 From c7e7c04274b13f98f758fb69b03f2ab61976ea80 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Fri, 16 Jul 2021 17:28:24 +0800 Subject: kernfs: use VFS negative dentry caching If there are many lookups for non-existent paths these negative lookups can lead to a lot of overhead during path walks. The VFS allows dentries to be created as negative and hashed, and caches them so they can be used to reduce the fairly high overhead alloc/free cycle that occurs during these lookups. Use the kernfs node parent revision to identify if a change has been made to the containing directory so that the negative dentry can be discarded and the lookup redone. Reviewed-by: Miklos Szeredi Signed-off-by: Ian Kent Link: https://lore.kernel.org/r/162642770420.63632.15791924970508867106.stgit@web.messagingengine.com Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index b3d1bc0f317d..0b21a8f961ac 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1039,9 +1039,31 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) if (flags & LOOKUP_RCU) return -ECHILD; - /* Always perform fresh lookup for negatives */ - if (d_really_is_negative(dentry)) - goto out_bad_unlocked; + /* Negative hashed dentry? */ + if (d_really_is_negative(dentry)) { + struct kernfs_node *parent; + + /* If the kernfs parent node has changed discard and + * proceed to ->lookup. + */ + mutex_lock(&kernfs_mutex); + spin_lock(&dentry->d_lock); + parent = kernfs_dentry_node(dentry->d_parent); + if (parent) { + if (kernfs_dir_changed(parent, dentry)) { + spin_unlock(&dentry->d_lock); + mutex_unlock(&kernfs_mutex); + return 0; + } + } + spin_unlock(&dentry->d_lock); + mutex_unlock(&kernfs_mutex); + + /* The kernfs parent node hasn't changed, leave the + * dentry negative and return success. + */ + return 1; + } kn = kernfs_dentry_node(dentry); mutex_lock(&kernfs_mutex); @@ -1067,7 +1089,6 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) return 1; out_bad: mutex_unlock(&kernfs_mutex); -out_bad_unlocked: return 0; } @@ -1082,33 +1103,27 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, struct dentry *ret; struct kernfs_node *parent = dir->i_private; struct kernfs_node *kn; - struct inode *inode; + struct inode *inode = NULL; const void *ns = NULL; mutex_lock(&kernfs_mutex); - if (kernfs_ns_enabled(parent)) ns = kernfs_info(dir->i_sb)->ns; kn = kernfs_find_ns(parent, dentry->d_name.name, ns); - - /* no such entry */ - if (!kn || !kernfs_active(kn)) { - ret = NULL; - goto out_unlock; - } - /* attach dentry and inode */ - inode = kernfs_get_inode(dir->i_sb, kn); - if (!inode) { - ret = ERR_PTR(-ENOMEM); - goto out_unlock; + if (kn && kernfs_active(kn)) { + inode = kernfs_get_inode(dir->i_sb, kn); + if (!inode) + inode = ERR_PTR(-ENOMEM); } - - /* instantiate and hash dentry */ + /* Needed only for negative dentry validation */ + if (!inode) + kernfs_set_rev(parent, dentry); + /* instantiate and hash (possibly negative) dentry */ ret = d_splice_alias(inode, dentry); - out_unlock: mutex_unlock(&kernfs_mutex); + return ret; } -- cgit v1.2.1 From 7ba0273b2f34a55efe967d3c7381fb1da2ca195f Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Fri, 16 Jul 2021 17:28:29 +0800 Subject: kernfs: switch kernfs to use an rwsem The kernfs global lock restricts the ability to perform kernfs node lookup operations in parallel during path walks. Change the kernfs mutex to an rwsem so that, when opportunity arises, node searches can be done in parallel with path walk lookups. Reviewed-by: Miklos Szeredi Signed-off-by: Ian Kent Link: https://lore.kernel.org/r/162642770946.63632.2218304587223241374.stgit@web.messagingengine.com Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 100 ++++++++++++++++++++++---------------------- fs/kernfs/file.c | 4 +- fs/kernfs/inode.c | 16 +++---- fs/kernfs/kernfs-internal.h | 5 ++- fs/kernfs/mount.c | 12 +++--- fs/kernfs/symlink.c | 4 +- include/linux/kernfs.h | 2 +- 7 files changed, 72 insertions(+), 71 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 0b21a8f961ac..4994723d6cf7 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -17,7 +17,7 @@ #include "kernfs-internal.h" -DEFINE_MUTEX(kernfs_mutex); +DECLARE_RWSEM(kernfs_rwsem); static DEFINE_SPINLOCK(kernfs_rename_lock); /* kn->parent and ->name */ static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by rename_lock */ static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ @@ -26,7 +26,7 @@ static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ static bool kernfs_active(struct kernfs_node *kn) { - lockdep_assert_held(&kernfs_mutex); + lockdep_assert_held(&kernfs_rwsem); return atomic_read(&kn->active) >= 0; } @@ -340,7 +340,7 @@ static int kernfs_sd_compare(const struct kernfs_node *left, * @kn->parent->dir.children. * * Locking: - * mutex_lock(kernfs_mutex) + * kernfs_rwsem held exclusive * * RETURNS: * 0 on susccess -EEXIST on failure. @@ -386,7 +386,7 @@ static int kernfs_link_sibling(struct kernfs_node *kn) * removed, %false if @kn wasn't on the rbtree. * * Locking: - * mutex_lock(kernfs_mutex) + * kernfs_rwsem held exclusive */ static bool kernfs_unlink_sibling(struct kernfs_node *kn) { @@ -457,14 +457,14 @@ void kernfs_put_active(struct kernfs_node *kn) * return after draining is complete. */ static void kernfs_drain(struct kernfs_node *kn) - __releases(&kernfs_mutex) __acquires(&kernfs_mutex) + __releases(&kernfs_rwsem) __acquires(&kernfs_rwsem) { struct kernfs_root *root = kernfs_root(kn); - lockdep_assert_held(&kernfs_mutex); + lockdep_assert_held_write(&kernfs_rwsem); WARN_ON_ONCE(kernfs_active(kn)); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); if (kernfs_lockdep(kn)) { rwsem_acquire(&kn->dep_map, 0, 0, _RET_IP_); @@ -483,7 +483,7 @@ static void kernfs_drain(struct kernfs_node *kn) kernfs_drain_open_files(kn); - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); } /** @@ -722,7 +722,7 @@ int kernfs_add_one(struct kernfs_node *kn) bool has_ns; int ret; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); ret = -EINVAL; has_ns = kernfs_ns_enabled(parent); @@ -753,7 +753,7 @@ int kernfs_add_one(struct kernfs_node *kn) ps_iattr->ia_mtime = ps_iattr->ia_ctime; } - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); /* * Activate the new node unless CREATE_DEACTIVATED is requested. @@ -767,7 +767,7 @@ int kernfs_add_one(struct kernfs_node *kn) return 0; out_unlock: - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); return ret; } @@ -788,7 +788,7 @@ static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent, bool has_ns = kernfs_ns_enabled(parent); unsigned int hash; - lockdep_assert_held(&kernfs_mutex); + lockdep_assert_held(&kernfs_rwsem); if (has_ns != (bool)ns) { WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", @@ -820,7 +820,7 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent, size_t len; char *p, *name; - lockdep_assert_held(&kernfs_mutex); + lockdep_assert_held_read(&kernfs_rwsem); /* grab kernfs_rename_lock to piggy back on kernfs_pr_cont_buf */ spin_lock_irq(&kernfs_rename_lock); @@ -860,10 +860,10 @@ struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, { struct kernfs_node *kn; - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); kn = kernfs_find_ns(parent, name, ns); kernfs_get(kn); - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); return kn; } @@ -884,10 +884,10 @@ struct kernfs_node *kernfs_walk_and_get_ns(struct kernfs_node *parent, { struct kernfs_node *kn; - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); kn = kernfs_walk_ns(parent, path, ns); kernfs_get(kn); - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); return kn; } @@ -1046,18 +1046,18 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) /* If the kernfs parent node has changed discard and * proceed to ->lookup. */ - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); spin_lock(&dentry->d_lock); parent = kernfs_dentry_node(dentry->d_parent); if (parent) { if (kernfs_dir_changed(parent, dentry)) { spin_unlock(&dentry->d_lock); - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); return 0; } } spin_unlock(&dentry->d_lock); - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); /* The kernfs parent node hasn't changed, leave the * dentry negative and return success. @@ -1066,7 +1066,7 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) } kn = kernfs_dentry_node(dentry); - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); /* The kernfs node has been deactivated */ if (!kernfs_active(kn)) @@ -1085,10 +1085,10 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) kernfs_info(dentry->d_sb)->ns != kn->ns) goto out_bad; - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); return 1; out_bad: - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); return 0; } @@ -1106,7 +1106,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, struct inode *inode = NULL; const void *ns = NULL; - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); if (kernfs_ns_enabled(parent)) ns = kernfs_info(dir->i_sb)->ns; @@ -1122,7 +1122,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, kernfs_set_rev(parent, dentry); /* instantiate and hash (possibly negative) dentry */ ret = d_splice_alias(inode, dentry); - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); return ret; } @@ -1244,7 +1244,7 @@ static struct kernfs_node *kernfs_next_descendant_post(struct kernfs_node *pos, { struct rb_node *rbn; - lockdep_assert_held(&kernfs_mutex); + lockdep_assert_held_write(&kernfs_rwsem); /* if first iteration, visit leftmost descendant which may be root */ if (!pos) @@ -1280,7 +1280,7 @@ void kernfs_activate(struct kernfs_node *kn) { struct kernfs_node *pos; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); pos = NULL; while ((pos = kernfs_next_descendant_post(pos, kn))) { @@ -1294,14 +1294,14 @@ void kernfs_activate(struct kernfs_node *kn) pos->flags |= KERNFS_ACTIVATED; } - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); } static void __kernfs_remove(struct kernfs_node *kn) { struct kernfs_node *pos; - lockdep_assert_held(&kernfs_mutex); + lockdep_assert_held_write(&kernfs_rwsem); /* * Short-circuit if non-root @kn has already finished removal. @@ -1324,7 +1324,7 @@ static void __kernfs_remove(struct kernfs_node *kn) pos = kernfs_leftmost_descendant(kn); /* - * kernfs_drain() drops kernfs_mutex temporarily and @pos's + * kernfs_drain() drops kernfs_rwsem temporarily and @pos's * base ref could have been put by someone else by the time * the function returns. Make sure it doesn't go away * underneath us. @@ -1371,9 +1371,9 @@ static void __kernfs_remove(struct kernfs_node *kn) */ void kernfs_remove(struct kernfs_node *kn) { - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); __kernfs_remove(kn); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); } /** @@ -1460,17 +1460,17 @@ bool kernfs_remove_self(struct kernfs_node *kn) { bool ret; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); kernfs_break_active_protection(kn); /* * SUICIDAL is used to arbitrate among competing invocations. Only * the first one will actually perform removal. When the removal * is complete, SUICIDED is set and the active ref is restored - * while holding kernfs_mutex. The ones which lost arbitration - * waits for SUICDED && drained which can happen only after the - * enclosing kernfs operation which executed the winning instance - * of kernfs_remove_self() finished. + * while kernfs_rwsem for held exclusive. The ones which lost + * arbitration waits for SUICIDED && drained which can happen only + * after the enclosing kernfs operation which executed the winning + * instance of kernfs_remove_self() finished. */ if (!(kn->flags & KERNFS_SUICIDAL)) { kn->flags |= KERNFS_SUICIDAL; @@ -1488,9 +1488,9 @@ bool kernfs_remove_self(struct kernfs_node *kn) atomic_read(&kn->active) == KN_DEACTIVATED_BIAS) break; - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); schedule(); - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); } finish_wait(waitq, &wait); WARN_ON_ONCE(!RB_EMPTY_NODE(&kn->rb)); @@ -1498,12 +1498,12 @@ bool kernfs_remove_self(struct kernfs_node *kn) } /* - * This must be done while holding kernfs_mutex; otherwise, waiting - * for SUICIDED && deactivated could finish prematurely. + * This must be done while kernfs_rwsem held exclusive; otherwise, + * waiting for SUICIDED && deactivated could finish prematurely. */ kernfs_unbreak_active_protection(kn); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); return ret; } @@ -1527,13 +1527,13 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, return -ENOENT; } - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); kn = kernfs_find_ns(parent, name, ns); if (kn) __kernfs_remove(kn); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); if (kn) return 0; @@ -1559,7 +1559,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, if (!kn->parent) return -EINVAL; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); error = -ENOENT; if (!kernfs_active(kn) || !kernfs_active(new_parent) || @@ -1613,7 +1613,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, error = 0; out: - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); return error; } @@ -1688,7 +1688,7 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) if (!dir_emit_dots(file, ctx)) return 0; - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); if (kernfs_ns_enabled(parent)) ns = kernfs_info(dentry->d_sb)->ns; @@ -1705,12 +1705,12 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) file->private_data = pos; kernfs_get(pos); - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); if (!dir_emit(ctx, name, len, ino, type)) return 0; - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); } - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); file->private_data = NULL; ctx->pos = INT_MAX; return 0; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index c75719312147..60e2a86c535e 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -860,7 +860,7 @@ repeat: spin_unlock_irq(&kernfs_notify_lock); /* kick fsnotify */ - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); list_for_each_entry(info, &kernfs_root(kn)->supers, node) { struct kernfs_node *parent; @@ -898,7 +898,7 @@ repeat: iput(inode); } - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); kernfs_put(kn); goto repeat; } diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 26f2aa3586f9..dad749f39518 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -100,9 +100,9 @@ int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { int ret; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); ret = __kernfs_setattr(kn, iattr); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); return ret; } @@ -116,7 +116,7 @@ int kernfs_iop_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, if (!kn) return -EINVAL; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); error = setattr_prepare(&init_user_ns, dentry, iattr); if (error) goto out; @@ -129,7 +129,7 @@ int kernfs_iop_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, setattr_copy(&init_user_ns, inode, iattr); out: - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); return error; } @@ -185,9 +185,9 @@ int kernfs_iop_getattr(struct user_namespace *mnt_userns, struct inode *inode = d_inode(path->dentry); struct kernfs_node *kn = inode->i_private; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); kernfs_refresh_inode(kn, inode); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); generic_fillattr(&init_user_ns, inode, stat); return 0; @@ -278,9 +278,9 @@ int kernfs_iop_permission(struct user_namespace *mnt_userns, kn = inode->i_private; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); kernfs_refresh_inode(kn, inode); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); return generic_permission(&init_user_ns, inode, mask); } diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index c2ae58f3b202..f9cc912c31e1 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -69,7 +70,7 @@ struct kernfs_super_info { */ const void *ns; - /* anchored at kernfs_root->supers, protected by kernfs_mutex */ + /* anchored at kernfs_root->supers, protected by kernfs_rwsem */ struct list_head node; }; #define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) @@ -121,7 +122,7 @@ int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr); /* * dir.c */ -extern struct mutex kernfs_mutex; +extern struct rw_semaphore kernfs_rwsem; extern const struct dentry_operations kernfs_dops; extern const struct file_operations kernfs_dir_fops; extern const struct inode_operations kernfs_dir_iops; diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 9dc7e7a64e10..baa4155ba2ed 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -255,9 +255,9 @@ static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *k sb->s_shrink.seeks = 0; /* get root inode, initialize and unlock it */ - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); inode = kernfs_get_inode(sb, info->root->kn); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); if (!inode) { pr_debug("kernfs: could not get root inode\n"); return -ENOMEM; @@ -344,9 +344,9 @@ int kernfs_get_tree(struct fs_context *fc) } sb->s_flags |= SB_ACTIVE; - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); list_add(&info->node, &info->root->supers); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); } fc->root = dget(sb->s_root); @@ -372,9 +372,9 @@ void kernfs_kill_sb(struct super_block *sb) { struct kernfs_super_info *info = kernfs_info(sb); - mutex_lock(&kernfs_mutex); + down_write(&kernfs_rwsem); list_del(&info->node); - mutex_unlock(&kernfs_mutex); + up_write(&kernfs_rwsem); /* * Remove the superblock from fs_supers/s_instances diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 5432883d819f..c8f8e41b8411 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -116,9 +116,9 @@ static int kernfs_getlink(struct inode *inode, char *path) struct kernfs_node *target = kn->symlink.target_kn; int error; - mutex_lock(&kernfs_mutex); + down_read(&kernfs_rwsem); error = kernfs_get_target_path(parent, target, path); - mutex_unlock(&kernfs_mutex); + up_read(&kernfs_rwsem); return error; } diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index d68b4ad09573..1093abf7c28c 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -193,7 +193,7 @@ struct kernfs_root { u32 id_highbits; struct kernfs_syscall_ops *syscall_ops; - /* list of kernfs_super_info of this root, protected by kernfs_mutex */ + /* list of kernfs_super_info of this root, protected by kernfs_rwsem */ struct list_head supers; wait_queue_head_t deactivate_waitq; -- cgit v1.2.1 From 47b5c64d0ab5e7136db2b78c6ec710e0d8a5a36b Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Fri, 16 Jul 2021 17:28:34 +0800 Subject: kernfs: use i_lock to protect concurrent inode updates The inode operations .permission() and .getattr() use the kernfs node write lock but all that's needed is the read lock to protect against partial updates of these kernfs node fields which are all done under the write lock. And .permission() is called frequently during path walks and can cause quite a bit of contention between kernfs node operations and path walks when the number of concurrent walks is high. To change kernfs_iop_getattr() and kernfs_iop_permission() to take the rw sem read lock instead of the write lock an additional lock is needed to protect against multiple processes concurrently updating the inode attributes and link count in kernfs_refresh_inode(). The inode i_lock seems like the sensible thing to use to protect these inode attribute updates so use it in kernfs_refresh_inode(). The last hunk in the patch, applied to kernfs_fill_super(), is possibly not needed but taking the lock was present originally. I prefer to continue to take it to protect against a partial update of the source kernfs fields during the call to kernfs_refresh_inode() made by kernfs_get_inode(). Reviewed-by: Miklos Szeredi Signed-off-by: Ian Kent Link: https://lore.kernel.org/r/162642771474.63632.16295959115893904470.stgit@web.messagingengine.com Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/inode.c | 18 ++++++++++++------ fs/kernfs/mount.c | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index dad749f39518..c0eae1725435 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -185,11 +185,13 @@ int kernfs_iop_getattr(struct user_namespace *mnt_userns, struct inode *inode = d_inode(path->dentry); struct kernfs_node *kn = inode->i_private; - down_write(&kernfs_rwsem); + down_read(&kernfs_rwsem); + spin_lock(&inode->i_lock); kernfs_refresh_inode(kn, inode); - up_write(&kernfs_rwsem); - generic_fillattr(&init_user_ns, inode, stat); + spin_unlock(&inode->i_lock); + up_read(&kernfs_rwsem); + return 0; } @@ -272,17 +274,21 @@ int kernfs_iop_permission(struct user_namespace *mnt_userns, struct inode *inode, int mask) { struct kernfs_node *kn; + int ret; if (mask & MAY_NOT_BLOCK) return -ECHILD; kn = inode->i_private; - down_write(&kernfs_rwsem); + down_read(&kernfs_rwsem); + spin_lock(&inode->i_lock); kernfs_refresh_inode(kn, inode); - up_write(&kernfs_rwsem); + ret = generic_permission(&init_user_ns, inode, mask); + spin_unlock(&inode->i_lock); + up_read(&kernfs_rwsem); - return generic_permission(&init_user_ns, inode, mask); + return ret; } int kernfs_xattr_get(struct kernfs_node *kn, const char *name, diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index baa4155ba2ed..f2f909d09f52 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -255,9 +255,9 @@ static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *k sb->s_shrink.seeks = 0; /* get root inode, initialize and unlock it */ - down_write(&kernfs_rwsem); + down_read(&kernfs_rwsem); inode = kernfs_get_inode(sb, info->root->kn); - up_write(&kernfs_rwsem); + up_read(&kernfs_rwsem); if (!inode) { pr_debug("kernfs: could not get root inode\n"); return -ENOMEM; -- cgit v1.2.1 From df6192f47d2311cf40cd4321cc59863a5853b665 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Fri, 16 Jul 2021 17:28:40 +0800 Subject: kernfs: dont call d_splice_alias() under kernfs node lock The call to d_splice_alias() in kernfs_iop_lookup() doesn't depend on any kernfs node so there's no reason to hold the kernfs node lock when calling it. Reviewed-by: Miklos Szeredi Signed-off-by: Ian Kent Link: https://lore.kernel.org/r/162642772000.63632.10672683419693513226.stgit@web.messagingengine.com Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 4994723d6cf7..ba581429bf7b 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1100,7 +1100,6 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { - struct dentry *ret; struct kernfs_node *parent = dir->i_private; struct kernfs_node *kn; struct inode *inode = NULL; @@ -1120,11 +1119,10 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, /* Needed only for negative dentry validation */ if (!inode) kernfs_set_rev(parent, dentry); - /* instantiate and hash (possibly negative) dentry */ - ret = d_splice_alias(inode, dentry); up_read(&kernfs_rwsem); - return ret; + /* instantiate and hash (possibly negative) dentry */ + return d_splice_alias(inode, dentry); } static int kernfs_iop_mkdir(struct user_namespace *mnt_userns, -- cgit v1.2.1 From b2c943e52705b211d1aa0633c9196150cf30be47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 27 Jul 2021 10:08:37 +0200 Subject: nubus: Make struct nubus_driver::remove return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nubus core ignores the return value of the remove callback (in nubus_device_remove()) and all implementers return 0 anyway. So make it impossible for future drivers to return an unused error code by changing the remove prototype to return void. Signed-off-by: Uwe Kleine-König Acked-by: Finn Thain Link: https://lore.kernel.org/r/20210727080840.3550927-3-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/8390/mac8390.c | 3 +-- drivers/net/ethernet/natsemi/macsonic.c | 4 +--- include/linux/nubus.h | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/8390/mac8390.c b/drivers/net/ethernet/8390/mac8390.c index 9aac7119d382..91b04abfd687 100644 --- a/drivers/net/ethernet/8390/mac8390.c +++ b/drivers/net/ethernet/8390/mac8390.c @@ -428,13 +428,12 @@ out: return err; } -static int mac8390_device_remove(struct nubus_board *board) +static void mac8390_device_remove(struct nubus_board *board) { struct net_device *dev = nubus_get_drvdata(board); unregister_netdev(dev); free_netdev(dev); - return 0; } static struct nubus_driver mac8390_driver = { diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c index 2289e1fe3741..8709d700e15a 100644 --- a/drivers/net/ethernet/natsemi/macsonic.c +++ b/drivers/net/ethernet/natsemi/macsonic.c @@ -603,7 +603,7 @@ out: return err; } -static int mac_sonic_nubus_remove(struct nubus_board *board) +static void mac_sonic_nubus_remove(struct nubus_board *board) { struct net_device *ndev = nubus_get_drvdata(board); struct sonic_local *lp = netdev_priv(ndev); @@ -613,8 +613,6 @@ static int mac_sonic_nubus_remove(struct nubus_board *board) SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), lp->descriptors, lp->descriptors_laddr); free_netdev(ndev); - - return 0; } static struct nubus_driver mac_sonic_nubus_driver = { diff --git a/include/linux/nubus.h b/include/linux/nubus.h index eba50b057f6f..392fc6c53e96 100644 --- a/include/linux/nubus.h +++ b/include/linux/nubus.h @@ -86,7 +86,7 @@ extern struct list_head nubus_func_rsrcs; struct nubus_driver { struct device_driver driver; int (*probe)(struct nubus_board *board); - int (*remove)(struct nubus_board *board); + void (*remove)(struct nubus_board *board); }; extern struct bus_type nubus_bus_type; -- cgit v1.2.1 From f52c9ccb86237378d354f7bd71b6fcc9f3ff7f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 30 Jul 2021 21:10:32 +0200 Subject: nubus: Simplify check in remove callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core only calls a remove callback when the device was successfully bound (aka probed) before. So dev->driver is never NULL and the respective check can just be dropped. Acked-by: Finn Thain Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210730191035.1455248-2-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/nubus/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nubus/bus.c b/drivers/nubus/bus.c index d9d04f27f89b..17fad660032c 100644 --- a/drivers/nubus/bus.c +++ b/drivers/nubus/bus.c @@ -33,7 +33,7 @@ static void nubus_device_remove(struct device *dev) { struct nubus_driver *ndrv = to_nubus_driver(dev->driver); - if (dev->driver && ndrv->remove) + if (ndrv->remove) ndrv->remove(to_nubus_board(dev)); } -- cgit v1.2.1 From fe976c4aadae80e4a5a3f665de685ce4f0b0426c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 30 Jul 2021 21:10:33 +0200 Subject: sh: superhyway: Simplify check in remove callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core only calls a remove callback when the device was successfully bound (aka probed) before. So dev->driver is never NULL. (And even if it was NULL, to_superhyway_driver(NULL) isn't ...) Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210730191035.1455248-3-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/sh/superhyway/superhyway.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c index c0ab904c76ec..44324abe21da 100644 --- a/drivers/sh/superhyway/superhyway.c +++ b/drivers/sh/superhyway/superhyway.c @@ -155,7 +155,7 @@ static void superhyway_device_remove(struct device *dev) struct superhyway_device *shyway_dev = to_superhyway_device(dev); struct superhyway_driver *shyway_drv = to_superhyway_driver(dev->driver); - if (shyway_drv && shyway_drv->remove) + if (shyway_drv->remove) shyway_drv->remove(shyway_dev); } -- cgit v1.2.1 From 18d214cc1d83af5dadf12c383686715497f20571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 30 Jul 2021 21:10:34 +0200 Subject: zorro: Simplify remove callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core only calls a remove callback when the device was successfully bound (aka probed) before. So dev->driver is never NULL. (And even if it was NULL, to_zorro_driver(NULL) isn't ...) Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210730191035.1455248-4-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/zorro/zorro-driver.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c index c18524bb8b2a..ab06c9ce2c78 100644 --- a/drivers/zorro/zorro-driver.c +++ b/drivers/zorro/zorro-driver.c @@ -67,11 +67,9 @@ static void zorro_device_remove(struct device *dev) struct zorro_dev *z = to_zorro_dev(dev); struct zorro_driver *drv = to_zorro_driver(dev->driver); - if (drv) { - if (drv->remove) - drv->remove(z); - z->driver = NULL; - } + if (drv->remove) + drv->remove(z); + z->driver = NULL; } -- cgit v1.2.1 From fac58b4a5287c9d37c39d09d9bdc80846b744649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 30 Jul 2021 21:10:35 +0200 Subject: zorro: Drop useless (and hardly used) .driver member in struct zorro_dev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only actual use is to check in zorro_device_probe() that the device isn't already bound. The driver core already ensures this however so the check can go away which allows to drop the then assigned-only member from struct zorro_dev. If the value was indeed needed somewhere it can always be calculated by to_zorro_driver(z->dev.driver) . Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210730191035.1455248-5-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/zorro/zorro-driver.c | 7 ++----- include/linux/zorro.h | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c index ab06c9ce2c78..96f068830549 100644 --- a/drivers/zorro/zorro-driver.c +++ b/drivers/zorro/zorro-driver.c @@ -47,16 +47,14 @@ static int zorro_device_probe(struct device *dev) struct zorro_driver *drv = to_zorro_driver(dev->driver); struct zorro_dev *z = to_zorro_dev(dev); - if (!z->driver && drv->probe) { + if (drv->probe) { const struct zorro_device_id *id; id = zorro_match_device(drv->id_table, z); if (id) error = drv->probe(z, id); - if (error >= 0) { - z->driver = drv; + if (error >= 0) error = 0; - } } return error; } @@ -69,7 +67,6 @@ static void zorro_device_remove(struct device *dev) if (drv->remove) drv->remove(z); - z->driver = NULL; } diff --git a/include/linux/zorro.h b/include/linux/zorro.h index e2e4de188d84..db7416ed6057 100644 --- a/include/linux/zorro.h +++ b/include/linux/zorro.h @@ -29,7 +29,6 @@ struct zorro_dev { struct ExpansionRom rom; zorro_id id; - struct zorro_driver *driver; /* which driver has allocated this device */ struct device dev; /* Generic device interface */ u16 slotaddr; u16 slotsize; -- cgit v1.2.1 From 112cedc8e600b668688eb809bf11817adec58ddc Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 2 Aug 2021 18:24:44 +0200 Subject: debugfs: Return error during {full/open}_proxy_open() on rmmod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a kernel module gets unloaded then it printed report about a leak before commit 275678e7a9be ("debugfs: Check module state before warning in {full/open}_proxy_open()"). An additional check was added in this commit to avoid this printing. But it was forgotten that the function must return an error in this case because it was not actually opened. As result, the systems started to crash or to hang when a module was unloaded while something was trying to open a file. Fixes: 275678e7a9be ("debugfs: Check module state before warning in {full/open}_proxy_open()") Cc: Taehee Yoo Reported-by: Mário Lopes Signed-off-by: Sven Eckelmann Link: https://lore.kernel.org/r/20210802162444.7848-1-sven@narfation.org Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/file.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index df00231d3ecc..7d162b0efbf0 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -179,8 +179,10 @@ static int open_proxy_open(struct inode *inode, struct file *filp) if (!fops_get(real_fops)) { #ifdef CONFIG_MODULES if (real_fops->owner && - real_fops->owner->state == MODULE_STATE_GOING) + real_fops->owner->state == MODULE_STATE_GOING) { + r = -ENXIO; goto out; + } #endif /* Huh? Module did not clean up after itself at exit? */ @@ -314,8 +316,10 @@ static int full_proxy_open(struct inode *inode, struct file *filp) if (!fops_get(real_fops)) { #ifdef CONFIG_MODULES if (real_fops->owner && - real_fops->owner->state == MODULE_STATE_GOING) + real_fops->owner->state == MODULE_STATE_GOING) { + r = -ENXIO; goto out; + } #endif /* Huh? Module did not cleanup after itself at exit? */ -- cgit v1.2.1 From 93bb8e352a9136a56dd26762bf54cf6554cfa96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Thu, 29 Jul 2021 23:32:34 +0000 Subject: sysfs: Invoke iomem_get_mapping() from the sysfs open callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defer invocation of the iomem_get_mapping() to the sysfs open callback so that it can be executed as needed when the binary sysfs object has been accessed. To do that, convert the "mapping" member of the struct bin_attribute from a pointer to the struct address_space into a function pointer with a signature that requires the same return type, and then updates the sysfs_kf_bin_open() to invoke provided function should the function pointer be valid. Also, convert every invocation of iomem_get_mapping() into a function pointer assignment, therefore allowing for the iomem_get_mapping() invocation to be deferred to when the sysfs open callback runs. Thus, this change removes the need for the fs_initcalls to complete before any other sub-system that uses the iomem_get_mapping() would be able to invoke it safely without leading to a failure and an Oops related to an invalid iomem_get_mapping() access. Suggested-by: Dan Williams Reviewed-by: Dan Williams Acked-by: Bjorn Helgaas Signed-off-by: Dan Williams Signed-off-by: Krzysztof Wilczyński Link: https://lore.kernel.org/r/20210729233235.1508920-2-kw@linux.com Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-sysfs.c | 6 +++--- fs/sysfs/file.c | 2 +- include/linux/sysfs.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 5d63df7c1820..76e5545d0e73 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -965,7 +965,7 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_io->read = pci_read_legacy_io; b->legacy_io->write = pci_write_legacy_io; b->legacy_io->mmap = pci_mmap_legacy_io; - b->legacy_io->mapping = iomem_get_mapping(); + b->legacy_io->mapping = iomem_get_mapping; pci_adjust_legacy_attr(b, pci_mmap_io); error = device_create_bin_file(&b->dev, b->legacy_io); if (error) @@ -978,7 +978,7 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_mem->size = 1024*1024; b->legacy_mem->attr.mode = 0600; b->legacy_mem->mmap = pci_mmap_legacy_mem; - b->legacy_io->mapping = iomem_get_mapping(); + b->legacy_io->mapping = iomem_get_mapping; pci_adjust_legacy_attr(b, pci_mmap_mem); error = device_create_bin_file(&b->dev, b->legacy_mem); if (error) @@ -1195,7 +1195,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) } } if (res_attr->mmap) - res_attr->mapping = iomem_get_mapping(); + res_attr->mapping = iomem_get_mapping; res_attr->attr.name = res_attr_name; res_attr->attr.mode = 0600; res_attr->size = pci_resource_len(pdev, num); diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 9aefa7779b29..a3ee4c32a264 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -175,7 +175,7 @@ static int sysfs_kf_bin_open(struct kernfs_open_file *of) struct bin_attribute *battr = of->kn->priv; if (battr->mapping) - of->file->f_mapping = battr->mapping; + of->file->f_mapping = battr->mapping(); return 0; } diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index a12556a4b93a..d5bcc897583c 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -176,7 +176,7 @@ struct bin_attribute { struct attribute attr; size_t size; void *private; - struct address_space *mapping; + struct address_space *(*mapping)(void); ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, -- cgit v1.2.1 From f06aff924f975881a6abf91d2af0078fc8cd37bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Thu, 29 Jul 2021 23:32:35 +0000 Subject: sysfs: Rename struct bin_attribute member to f_mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two users of iomem_get_mapping(), the struct file and struct bin_attribute. The former has a member called "f_mapping" and the latter has a member called "mapping", and both are poniters to struct address_space. Rename struct bin_attribute member to "f_mapping" to keep both meaning and the usage consistent with other users of iomem_get_mapping(). Acked-by: Bjorn Helgaas Signed-off-by: Krzysztof Wilczyński Link: https://lore.kernel.org/r/20210729233235.1508920-3-kw@linux.com Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-sysfs.c | 6 +++--- fs/sysfs/file.c | 4 ++-- include/linux/sysfs.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 76e5545d0e73..f65382915f01 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -965,7 +965,7 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_io->read = pci_read_legacy_io; b->legacy_io->write = pci_write_legacy_io; b->legacy_io->mmap = pci_mmap_legacy_io; - b->legacy_io->mapping = iomem_get_mapping; + b->legacy_io->f_mapping = iomem_get_mapping; pci_adjust_legacy_attr(b, pci_mmap_io); error = device_create_bin_file(&b->dev, b->legacy_io); if (error) @@ -978,7 +978,7 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_mem->size = 1024*1024; b->legacy_mem->attr.mode = 0600; b->legacy_mem->mmap = pci_mmap_legacy_mem; - b->legacy_io->mapping = iomem_get_mapping; + b->legacy_io->f_mapping = iomem_get_mapping; pci_adjust_legacy_attr(b, pci_mmap_mem); error = device_create_bin_file(&b->dev, b->legacy_mem); if (error) @@ -1195,7 +1195,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) } } if (res_attr->mmap) - res_attr->mapping = iomem_get_mapping; + res_attr->f_mapping = iomem_get_mapping; res_attr->attr.name = res_attr_name; res_attr->attr.mode = 0600; res_attr->size = pci_resource_len(pdev, num); diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index a3ee4c32a264..d019d6ac6ad0 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -174,8 +174,8 @@ static int sysfs_kf_bin_open(struct kernfs_open_file *of) { struct bin_attribute *battr = of->kn->priv; - if (battr->mapping) - of->file->f_mapping = battr->mapping(); + if (battr->f_mapping) + of->file->f_mapping = battr->f_mapping(); return 0; } diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index d5bcc897583c..e3f1e8ac1f85 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -176,7 +176,7 @@ struct bin_attribute { struct attribute attr; size_t size; void *private; - struct address_space *(*mapping)(void); + struct address_space *(*f_mapping)(void); ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, -- cgit v1.2.1 From 1fae562983ca5c7eb36d4974be5e235374661806 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 6 Aug 2021 23:02:47 +1200 Subject: cpumask: introduce cpumap_print_list/bitmask_to_buf to support large bitmask and list The existing cpumap_print_to_pagebuf() is used by cpu topology and other drivers to export hexadecimal bitmask and decimal list to userspace by sysfs ABI. Right now, those drivers are using a normal attribute for this kind of ABIs. A normal attribute typically has show entry as below: static ssize_t example_dev_show(struct device *dev, struct device_attribute *attr, char *buf) { ... return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu); } show entry of attribute has no offset and count parameters and this means the file is limited to one page only. cpumap_print_to_pagebuf() API works terribly well for this kind of normal attribute with buf parameter and without offset, count: static inline ssize_t cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) { return bitmap_print_to_pagebuf(list, buf, cpumask_bits(mask), nr_cpu_ids); } The problem is once we have many cpus, we have a chance to make bitmask or list more than one page. Especially for list, it could be as complex as 0,3,5,7,9,...... We have no simple way to know it exact size. It turns out bin_attribute is a way to break this limit. bin_attribute has show entry as below: static ssize_t example_bin_attribute_show(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t offset, size_t count) { ... } With the new offset and count parameters, this makes sysfs ABI be able to support file size more than one page. For example, offset could be >= 4096. This patch introduces cpumap_print_bitmask/list_to_buf() and their bitmap infrastructure bitmap_print_bitmask/list_to_buf() so that those drivers can move to bin_attribute to support large bitmask and list. At the same time, we have to pass those corresponding parameters such as offset, count from bin_attribute to this new API. Cc: Andrew Morton Cc: Andy Shevchenko Cc: Randy Dunlap Cc: Stefano Brivio Cc: Alexander Gordeev Cc: "Ma, Jianpeng" Cc: Yury Norov Cc: Valentin Schneider Cc: Peter Zijlstra Cc: Daniel Bristot de Oliveira Reviewed-by: Jonathan Cameron Signed-off-by: Tian Tao Signed-off-by: Barry Song Link: https://lore.kernel.org/r/20210806110251.560-2-song.bao.hua@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- include/linux/bitmap.h | 6 +++ include/linux/cpumask.h | 38 ++++++++++++++++++ lib/bitmap.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index a36cfcec4e77..37f36dad18bd 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -227,6 +227,12 @@ unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int ord, un int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, int nmaskbits); +extern int bitmap_print_bitmask_to_buf(char *buf, const unsigned long *maskp, + int nmaskbits, loff_t off, size_t count); + +extern int bitmap_print_list_to_buf(char *buf, const unsigned long *maskp, + int nmaskbits, loff_t off, size_t count); + #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index f3689a52bfd0..5d4d07a9e1ed 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -983,6 +983,44 @@ cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) nr_cpu_ids); } +/** + * cpumap_print_bitmask_to_buf - copies the cpumask into the buffer as + * hex values of cpumask + * + * @buf: the buffer to copy into + * @mask: the cpumask to copy + * @off: in the string from which we are copying, we copy to @buf + * @count: the maximum number of bytes to print + * + * The function prints the cpumask into the buffer as hex values of + * cpumask; Typically used by bin_attribute to export cpumask bitmask + * ABI. + * + * Returns the length of how many bytes have been copied. + */ +static inline ssize_t +cpumap_print_bitmask_to_buf(char *buf, const struct cpumask *mask, + loff_t off, size_t count) +{ + return bitmap_print_bitmask_to_buf(buf, cpumask_bits(mask), + nr_cpu_ids, off, count); +} + +/** + * cpumap_print_list_to_buf - copies the cpumask into the buffer as + * comma-separated list of cpus + * + * Everything is same with the above cpumap_print_bitmask_to_buf() + * except the print format. + */ +static inline ssize_t +cpumap_print_list_to_buf(char *buf, const struct cpumask *mask, + loff_t off, size_t count) +{ + return bitmap_print_list_to_buf(buf, cpumask_bits(mask), + nr_cpu_ids, off, count); +} + #if NR_CPUS <= BITS_PER_LONG #define CPU_MASK_ALL \ (cpumask_t) { { \ diff --git a/lib/bitmap.c b/lib/bitmap.c index 9401d39e4722..73746d96af81 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -487,6 +487,109 @@ int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, } EXPORT_SYMBOL(bitmap_print_to_pagebuf); +/** + * bitmap_print_to_buf - convert bitmap to list or hex format ASCII string + * @list: indicates whether the bitmap must be list + * true: print in decimal list format + * false: print in hexadecimal bitmask format + */ +static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp, + int nmaskbits, loff_t off, size_t count) +{ + const char *fmt = list ? "%*pbl\n" : "%*pb\n"; + ssize_t size; + void *data; + + data = kasprintf(GFP_KERNEL, fmt, nmaskbits, maskp); + if (!data) + return -ENOMEM; + + size = memory_read_from_buffer(buf, count, &off, data, strlen(data) + 1); + kfree(data); + + return size; +} + +/** + * bitmap_print_bitmask_to_buf - convert bitmap to hex bitmask format ASCII string + * + * The bitmap_print_to_pagebuf() is used indirectly via its cpumap wrapper + * cpumap_print_to_pagebuf() or directly by drivers to export hexadecimal + * bitmask and decimal list to userspace by sysfs ABI. + * Drivers might be using a normal attribute for this kind of ABIs. A + * normal attribute typically has show entry as below: + * static ssize_t example_attribute_show(struct device *dev, + * struct device_attribute *attr, char *buf) + * { + * ... + * return bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max); + * } + * show entry of attribute has no offset and count parameters and this + * means the file is limited to one page only. + * bitmap_print_to_pagebuf() API works terribly well for this kind of + * normal attribute with buf parameter and without offset, count: + * bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, + * int nmaskbits) + * { + * } + * The problem is once we have a large bitmap, we have a chance to get a + * bitmask or list more than one page. Especially for list, it could be + * as complex as 0,3,5,7,9,... We have no simple way to know it exact size. + * It turns out bin_attribute is a way to break this limit. bin_attribute + * has show entry as below: + * static ssize_t + * example_bin_attribute_show(struct file *filp, struct kobject *kobj, + * struct bin_attribute *attr, char *buf, + * loff_t offset, size_t count) + * { + * ... + * } + * With the new offset and count parameters, this makes sysfs ABI be able + * to support file size more than one page. For example, offset could be + * >= 4096. + * bitmap_print_bitmask_to_buf(), bitmap_print_list_to_buf() wit their + * cpumap wrapper cpumap_print_bitmask_to_buf(), cpumap_print_list_to_buf() + * make those drivers be able to support large bitmask and list after they + * move to use bin_attribute. In result, we have to pass the corresponding + * parameters such as off, count from bin_attribute show entry to this API. + * + * @buf: buffer into which string is placed + * @maskp: pointer to bitmap to convert + * @nmaskbits: size of bitmap, in bits + * @off: in the string from which we are copying, We copy to @buf + * @count: the maximum number of bytes to print + * + * The role of cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf() + * is similar with cpumap_print_to_pagebuf(), the difference is that + * bitmap_print_to_pagebuf() mainly serves sysfs attribute with the assumption + * the destination buffer is exactly one page and won't be more than one page. + * cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf(), on the other + * hand, mainly serves bin_attribute which doesn't work with exact one page, + * and it can break the size limit of converted decimal list and hexadecimal + * bitmask. + * + * Returns the number of characters actually printed to @buf + */ +int bitmap_print_bitmask_to_buf(char *buf, const unsigned long *maskp, + int nmaskbits, loff_t off, size_t count) +{ + return bitmap_print_to_buf(false, buf, maskp, nmaskbits, off, count); +} +EXPORT_SYMBOL(bitmap_print_bitmask_to_buf); + +/** + * bitmap_print_list_to_buf - convert bitmap to decimal list format ASCII string + * + * Everything is same with the above bitmap_print_bitmask_to_buf() except + * the print format. + */ +int bitmap_print_list_to_buf(char *buf, const unsigned long *maskp, + int nmaskbits, loff_t off, size_t count) +{ + return bitmap_print_to_buf(true, buf, maskp, nmaskbits, off, count); +} +EXPORT_SYMBOL(bitmap_print_list_to_buf); + /* * Region 9-38:4/10 describes the following bitmap structure: * 0 9 12 18 38 N -- cgit v1.2.1 From 291f93ca339f5b5e6e90ad037bb8271f0f618165 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 6 Aug 2021 23:02:48 +1200 Subject: lib: test_bitmap: add bitmap_print_bitmask/list_to_buf test cases The added test items cover both cases where bitmap buf of the printed result is greater than and less than 4KB. And it also covers the case where offset for printing is non-zero which will happen when printed buf is larger than one page in sysfs bin_attribute. Reported-by: kernel test robot Reviewed-by: Andy Shevchenko Signed-off-by: Barry Song Link: https://lore.kernel.org/r/20210806110251.560-3-song.bao.hua@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- lib/test_bitmap.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index 4ea73f5aed41..d33fa5a61b95 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c @@ -19,6 +19,7 @@ KSTM_MODULE_GLOBALS(); static char pbl_buffer[PAGE_SIZE] __initdata; +static char print_buf[PAGE_SIZE * 2] __initdata; static const unsigned long exp1[] __initconst = { BITMAP_FROM_U64(1), @@ -156,6 +157,20 @@ static bool __init __check_eq_clump8(const char *srcfile, unsigned int line, return true; } +static bool __init +__check_eq_str(const char *srcfile, unsigned int line, + const char *exp_str, const char *str, + unsigned int len) +{ + bool eq; + + eq = strncmp(exp_str, str, len) == 0; + if (!eq) + pr_err("[%s:%u] expected %s, got %s\n", srcfile, line, exp_str, str); + + return eq; +} + #define __expect_eq(suffix, ...) \ ({ \ int result = 0; \ @@ -173,6 +188,7 @@ static bool __init __check_eq_clump8(const char *srcfile, unsigned int line, #define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__) #define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__) #define expect_eq_clump8(...) __expect_eq(clump8, ##__VA_ARGS__) +#define expect_eq_str(...) __expect_eq(str, ##__VA_ARGS__) static void __init test_zero_clear(void) { @@ -660,6 +676,139 @@ static void __init test_bitmap_cut(void) } } +struct test_bitmap_print { + const unsigned long *bitmap; + unsigned long nbits; + const char *mask; + const char *list; +}; + +static const unsigned long small_bitmap[] __initconst = { + BITMAP_FROM_U64(0x3333333311111111ULL), +}; + +static const char small_mask[] __initconst = "33333333,11111111\n"; +static const char small_list[] __initconst = "0,4,8,12,16,20,24,28,32-33,36-37,40-41,44-45,48-49,52-53,56-57,60-61\n"; + +static const unsigned long large_bitmap[] __initconst = { + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), +}; + +static const char large_mask[] __initconst = "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111," + "33333333,11111111,33333333,11111111\n"; + +static const char large_list[] __initconst = /* more than 4KB */ + "0,4,8,12,16,20,24,28,32-33,36-37,40-41,44-45,48-49,52-53,56-57,60-61,64,68,72,76,80,84,88,92,96-97,100-101,104-1" + "05,108-109,112-113,116-117,120-121,124-125,128,132,136,140,144,148,152,156,160-161,164-165,168-169,172-173,176-1" + "77,180-181,184-185,188-189,192,196,200,204,208,212,216,220,224-225,228-229,232-233,236-237,240-241,244-245,248-2" + "49,252-253,256,260,264,268,272,276,280,284,288-289,292-293,296-297,300-301,304-305,308-309,312-313,316-317,320,3" + "24,328,332,336,340,344,348,352-353,356-357,360-361,364-365,368-369,372-373,376-377,380-381,384,388,392,396,400,4" + "04,408,412,416-417,420-421,424-425,428-429,432-433,436-437,440-441,444-445,448,452,456,460,464,468,472,476,480-4" + "81,484-485,488-489,492-493,496-497,500-501,504-505,508-509,512,516,520,524,528,532,536,540,544-545,548-549,552-5" + "53,556-557,560-561,564-565,568-569,572-573,576,580,584,588,592,596,600,604,608-609,612-613,616-617,620-621,624-6" + "25,628-629,632-633,636-637,640,644,648,652,656,660,664,668,672-673,676-677,680-681,684-685,688-689,692-693,696-6" + "97,700-701,704,708,712,716,720,724,728,732,736-737,740-741,744-745,748-749,752-753,756-757,760-761,764-765,768,7" + "72,776,780,784,788,792,796,800-801,804-805,808-809,812-813,816-817,820-821,824-825,828-829,832,836,840,844,848,8" + "52,856,860,864-865,868-869,872-873,876-877,880-881,884-885,888-889,892-893,896,900,904,908,912,916,920,924,928-9" + "29,932-933,936-937,940-941,944-945,948-949,952-953,956-957,960,964,968,972,976,980,984,988,992-993,996-997,1000-" + "1001,1004-1005,1008-1009,1012-1013,1016-1017,1020-1021,1024,1028,1032,1036,1040,1044,1048,1052,1056-1057,1060-10" + "61,1064-1065,1068-1069,1072-1073,1076-1077,1080-1081,1084-1085,1088,1092,1096,1100,1104,1108,1112,1116,1120-1121" + ",1124-1125,1128-1129,1132-1133,1136-1137,1140-1141,1144-1145,1148-1149,1152,1156,1160,1164,1168,1172,1176,1180,1" + "184-1185,1188-1189,1192-1193,1196-1197,1200-1201,1204-1205,1208-1209,1212-1213,1216,1220,1224,1228,1232,1236,124" + "0,1244,1248-1249,1252-1253,1256-1257,1260-1261,1264-1265,1268-1269,1272-1273,1276-1277,1280,1284,1288,1292,1296," + "1300,1304,1308,1312-1313,1316-1317,1320-1321,1324-1325,1328-1329,1332-1333,1336-1337,1340-1341,1344,1348,1352,13" + "56,1360,1364,1368,1372,1376-1377,1380-1381,1384-1385,1388-1389,1392-1393,1396-1397,1400-1401,1404-1405,1408,1412" + ",1416,1420,1424,1428,1432,1436,1440-1441,1444-1445,1448-1449,1452-1453,1456-1457,1460-1461,1464-1465,1468-1469,1" + "472,1476,1480,1484,1488,1492,1496,1500,1504-1505,1508-1509,1512-1513,1516-1517,1520-1521,1524-1525,1528-1529,153" + "2-1533,1536,1540,1544,1548,1552,1556,1560,1564,1568-1569,1572-1573,1576-1577,1580-1581,1584-1585,1588-1589,1592-" + "1593,1596-1597,1600,1604,1608,1612,1616,1620,1624,1628,1632-1633,1636-1637,1640-1641,1644-1645,1648-1649,1652-16" + "53,1656-1657,1660-1661,1664,1668,1672,1676,1680,1684,1688,1692,1696-1697,1700-1701,1704-1705,1708-1709,1712-1713" + ",1716-1717,1720-1721,1724-1725,1728,1732,1736,1740,1744,1748,1752,1756,1760-1761,1764-1765,1768-1769,1772-1773,1" + "776-1777,1780-1781,1784-1785,1788-1789,1792,1796,1800,1804,1808,1812,1816,1820,1824-1825,1828-1829,1832-1833,183" + "6-1837,1840-1841,1844-1845,1848-1849,1852-1853,1856,1860,1864,1868,1872,1876,1880,1884,1888-1889,1892-1893,1896-" + "1897,1900-1901,1904-1905,1908-1909,1912-1913,1916-1917,1920,1924,1928,1932,1936,1940,1944,1948,1952-1953,1956-19" + "57,1960-1961,1964-1965,1968-1969,1972-1973,1976-1977,1980-1981,1984,1988,1992,1996,2000,2004,2008,2012,2016-2017" + ",2020-2021,2024-2025,2028-2029,2032-2033,2036-2037,2040-2041,2044-2045,2048,2052,2056,2060,2064,2068,2072,2076,2" + "080-2081,2084-2085,2088-2089,2092-2093,2096-2097,2100-2101,2104-2105,2108-2109,2112,2116,2120,2124,2128,2132,213" + "6,2140,2144-2145,2148-2149,2152-2153,2156-2157,2160-2161,2164-2165,2168-2169,2172-2173,2176,2180,2184,2188,2192," + "2196,2200,2204,2208-2209,2212-2213,2216-2217,2220-2221,2224-2225,2228-2229,2232-2233,2236-2237,2240,2244,2248,22" + "52,2256,2260,2264,2268,2272-2273,2276-2277,2280-2281,2284-2285,2288-2289,2292-2293,2296-2297,2300-2301,2304,2308" + ",2312,2316,2320,2324,2328,2332,2336-2337,2340-2341,2344-2345,2348-2349,2352-2353,2356-2357,2360-2361,2364-2365,2" + "368,2372,2376,2380,2384,2388,2392,2396,2400-2401,2404-2405,2408-2409,2412-2413,2416-2417,2420-2421,2424-2425,242" + "8-2429,2432,2436,2440,2444,2448,2452,2456,2460,2464-2465,2468-2469,2472-2473,2476-2477,2480-2481,2484-2485,2488-" + "2489,2492-2493,2496,2500,2504,2508,2512,2516,2520,2524,2528-2529,2532-2533,2536-2537,2540-2541,2544-2545,2548-25" + "49,2552-2553,2556-2557\n"; + +static const struct test_bitmap_print test_print[] __initconst = { + { small_bitmap, sizeof(small_bitmap) * BITS_PER_BYTE, small_mask, small_list }, + { large_bitmap, sizeof(large_bitmap) * BITS_PER_BYTE, large_mask, large_list }, +}; + +static void __init test_bitmap_print_buf(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(test_print); i++) { + const struct test_bitmap_print *t = &test_print[i]; + int n; + + n = bitmap_print_bitmask_to_buf(print_buf, t->bitmap, t->nbits, + 0, 2 * PAGE_SIZE); + expect_eq_uint(strlen(t->mask) + 1, n); + expect_eq_str(t->mask, print_buf, n); + + n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits, + 0, 2 * PAGE_SIZE); + expect_eq_uint(strlen(t->list) + 1, n); + expect_eq_str(t->list, print_buf, n); + + /* test by non-zero offset */ + if (strlen(t->list) > PAGE_SIZE) { + n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits, + PAGE_SIZE, PAGE_SIZE); + expect_eq_uint(strlen(t->list) + 1 - PAGE_SIZE, n); + expect_eq_str(t->list + PAGE_SIZE, print_buf, n); + } + } +} + static void __init selftest(void) { test_zero_clear(); @@ -672,6 +821,7 @@ static void __init selftest(void) test_mem_optimisations(); test_for_each_set_clump8(); test_bitmap_cut(); + test_bitmap_print_buf(); } KSTM_MODULE_LOADERS(test_bitmap); -- cgit v1.2.1 From bb9ec13d156e85dfd6a8afd0bb61ccf5736ed257 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 6 Aug 2021 23:02:49 +1200 Subject: topology: use bin_attribute to break the size limitation of cpumap ABI Reading /sys/devices/system/cpu/cpuX/topology/ returns cpu topology. However, the size of this file is limited to PAGE_SIZE because of the limitation for sysfs attribute. This patch moves to use bin_attribute to extend the ABI to be more than one page so that cpumap bitmask and list won't be potentially trimmed. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Reviewed-by: Jonathan Cameron Signed-off-by: Tian Tao Signed-off-by: Barry Song Link: https://lore.kernel.org/r/20210806110251.560-4-song.bao.hua@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/topology.c | 115 ++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 52 deletions(-) diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 4d254fcc93d1..43c0940643f5 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -21,25 +21,27 @@ static ssize_t name##_show(struct device *dev, \ return sysfs_emit(buf, "%d\n", topology_##name(dev->id)); \ } -#define define_siblings_show_map(name, mask) \ -static ssize_t name##_show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - return cpumap_print_to_pagebuf(false, buf, topology_##mask(dev->id));\ +#define define_siblings_read_func(name, mask) \ +static ssize_t name##_read(struct file *file, struct kobject *kobj, \ + struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + struct device *dev = kobj_to_dev(kobj); \ + \ + return cpumap_print_bitmask_to_buf(buf, topology_##mask(dev->id), \ + off, count); \ +} \ + \ +static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \ + struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + struct device *dev = kobj_to_dev(kobj); \ + \ + return cpumap_print_list_to_buf(buf, topology_##mask(dev->id), \ + off, count); \ } -#define define_siblings_show_list(name, mask) \ -static ssize_t name##_list_show(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return cpumap_print_to_pagebuf(true, buf, topology_##mask(dev->id));\ -} - -#define define_siblings_show_func(name, mask) \ - define_siblings_show_map(name, mask); \ - define_siblings_show_list(name, mask) - define_id_show_func(physical_package_id); static DEVICE_ATTR_RO(physical_package_id); @@ -49,71 +51,80 @@ static DEVICE_ATTR_RO(die_id); define_id_show_func(core_id); static DEVICE_ATTR_RO(core_id); -define_siblings_show_func(thread_siblings, sibling_cpumask); -static DEVICE_ATTR_RO(thread_siblings); -static DEVICE_ATTR_RO(thread_siblings_list); +define_siblings_read_func(thread_siblings, sibling_cpumask); +static BIN_ATTR_RO(thread_siblings, 0); +static BIN_ATTR_RO(thread_siblings_list, 0); -define_siblings_show_func(core_cpus, sibling_cpumask); -static DEVICE_ATTR_RO(core_cpus); -static DEVICE_ATTR_RO(core_cpus_list); +define_siblings_read_func(core_cpus, sibling_cpumask); +static BIN_ATTR_RO(core_cpus, 0); +static BIN_ATTR_RO(core_cpus_list, 0); -define_siblings_show_func(core_siblings, core_cpumask); -static DEVICE_ATTR_RO(core_siblings); -static DEVICE_ATTR_RO(core_siblings_list); +define_siblings_read_func(core_siblings, core_cpumask); +static BIN_ATTR_RO(core_siblings, 0); +static BIN_ATTR_RO(core_siblings_list, 0); -define_siblings_show_func(die_cpus, die_cpumask); -static DEVICE_ATTR_RO(die_cpus); -static DEVICE_ATTR_RO(die_cpus_list); +define_siblings_read_func(die_cpus, die_cpumask); +static BIN_ATTR_RO(die_cpus, 0); +static BIN_ATTR_RO(die_cpus_list, 0); -define_siblings_show_func(package_cpus, core_cpumask); -static DEVICE_ATTR_RO(package_cpus); -static DEVICE_ATTR_RO(package_cpus_list); +define_siblings_read_func(package_cpus, core_cpumask); +static BIN_ATTR_RO(package_cpus, 0); +static BIN_ATTR_RO(package_cpus_list, 0); #ifdef CONFIG_SCHED_BOOK define_id_show_func(book_id); static DEVICE_ATTR_RO(book_id); -define_siblings_show_func(book_siblings, book_cpumask); -static DEVICE_ATTR_RO(book_siblings); -static DEVICE_ATTR_RO(book_siblings_list); +define_siblings_read_func(book_siblings, book_cpumask); +static BIN_ATTR_RO(book_siblings, 0); +static BIN_ATTR_RO(book_siblings_list, 0); #endif #ifdef CONFIG_SCHED_DRAWER define_id_show_func(drawer_id); static DEVICE_ATTR_RO(drawer_id); -define_siblings_show_func(drawer_siblings, drawer_cpumask); -static DEVICE_ATTR_RO(drawer_siblings); -static DEVICE_ATTR_RO(drawer_siblings_list); +define_siblings_read_func(drawer_siblings, drawer_cpumask); +static BIN_ATTR_RO(drawer_siblings, 0); +static BIN_ATTR_RO(drawer_siblings_list, 0); #endif +static struct bin_attribute *bin_attrs[] = { + &bin_attr_core_cpus, + &bin_attr_core_cpus_list, + &bin_attr_thread_siblings, + &bin_attr_thread_siblings_list, + &bin_attr_core_siblings, + &bin_attr_core_siblings_list, + &bin_attr_die_cpus, + &bin_attr_die_cpus_list, + &bin_attr_package_cpus, + &bin_attr_package_cpus_list, +#ifdef CONFIG_SCHED_BOOK + &bin_attr_book_siblings, + &bin_attr_book_siblings_list, +#endif +#ifdef CONFIG_SCHED_DRAWER + &bin_attr_drawer_siblings, + &bin_attr_drawer_siblings_list, +#endif + NULL +}; + static struct attribute *default_attrs[] = { &dev_attr_physical_package_id.attr, &dev_attr_die_id.attr, &dev_attr_core_id.attr, - &dev_attr_thread_siblings.attr, - &dev_attr_thread_siblings_list.attr, - &dev_attr_core_cpus.attr, - &dev_attr_core_cpus_list.attr, - &dev_attr_core_siblings.attr, - &dev_attr_core_siblings_list.attr, - &dev_attr_die_cpus.attr, - &dev_attr_die_cpus_list.attr, - &dev_attr_package_cpus.attr, - &dev_attr_package_cpus_list.attr, #ifdef CONFIG_SCHED_BOOK &dev_attr_book_id.attr, - &dev_attr_book_siblings.attr, - &dev_attr_book_siblings_list.attr, #endif #ifdef CONFIG_SCHED_DRAWER &dev_attr_drawer_id.attr, - &dev_attr_drawer_siblings.attr, - &dev_attr_drawer_siblings_list.attr, #endif NULL }; static const struct attribute_group topology_attr_group = { .attrs = default_attrs, + .bin_attrs = bin_attrs, .name = "topology" }; -- cgit v1.2.1 From 75bd50fa841db5434728d238b8b5659498ccf0ab Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 6 Aug 2021 23:02:50 +1200 Subject: drivers/base/node.c: use bin_attribute to break the size limitation of cpumap ABI Reading /sys/devices/system/cpu/cpuX/nodeX/ returns cpumap and cpulist. However, the size of this file is limited to PAGE_SIZE because of the limitation for sysfs attribute. This patch moves to use bin_attribute to extend the ABI to be more than one page so that cpumap bitmask and list won't be potentially trimmed. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Reviewed-by: Jonathan Cameron Signed-off-by: Tian Tao Signed-off-by: Barry Song Link: https://lore.kernel.org/r/20210806110251.560-5-song.bao.hua@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/node.c | 63 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/drivers/base/node.c b/drivers/base/node.c index 2bc9089f3e78..be16bbff11cc 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -26,43 +26,47 @@ static struct bus_type node_subsys = { .dev_name = "node", }; - -static ssize_t node_read_cpumap(struct device *dev, bool list, char *buf) +static inline ssize_t cpumap_read(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { - ssize_t n; - cpumask_var_t mask; + struct device *dev = kobj_to_dev(kobj); struct node *node_dev = to_node(dev); - - /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */ - BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1)); + cpumask_var_t mask; + ssize_t n; if (!alloc_cpumask_var(&mask, GFP_KERNEL)) return 0; cpumask_and(mask, cpumask_of_node(node_dev->dev.id), cpu_online_mask); - n = cpumap_print_to_pagebuf(list, buf, mask); + n = cpumap_print_bitmask_to_buf(buf, mask, off, count); free_cpumask_var(mask); return n; } -static inline ssize_t cpumap_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static BIN_ATTR_RO(cpumap, 0); + +static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { - return node_read_cpumap(dev, false, buf); -} + struct device *dev = kobj_to_dev(kobj); + struct node *node_dev = to_node(dev); + cpumask_var_t mask; + ssize_t n; + + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + return 0; -static DEVICE_ATTR_RO(cpumap); + cpumask_and(mask, cpumask_of_node(node_dev->dev.id), cpu_online_mask); + n = cpumap_print_list_to_buf(buf, mask, off, count); + free_cpumask_var(mask); -static inline ssize_t cpulist_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return node_read_cpumap(dev, true, buf); + return n; } -static DEVICE_ATTR_RO(cpulist); +static BIN_ATTR_RO(cpulist, 0); /** * struct node_access_nodes - Access class device to hold user visible @@ -557,15 +561,28 @@ static ssize_t node_read_distance(struct device *dev, static DEVICE_ATTR(distance, 0444, node_read_distance, NULL); static struct attribute *node_dev_attrs[] = { - &dev_attr_cpumap.attr, - &dev_attr_cpulist.attr, &dev_attr_meminfo.attr, &dev_attr_numastat.attr, &dev_attr_distance.attr, &dev_attr_vmstat.attr, NULL }; -ATTRIBUTE_GROUPS(node_dev); + +static struct bin_attribute *node_dev_bin_attrs[] = { + &bin_attr_cpumap, + &bin_attr_cpulist, + NULL +}; + +static const struct attribute_group node_dev_group = { + .attrs = node_dev_attrs, + .bin_attrs = node_dev_bin_attrs +}; + +static const struct attribute_group *node_dev_groups[] = { + &node_dev_group, + NULL +}; #ifdef CONFIG_HUGETLBFS /* -- cgit v1.2.1 From 3b35f2a6a625126c57475aa56b5357d8e80b404c Mon Sep 17 00:00:00 2001 From: Yury Norov Date: Fri, 6 Aug 2021 23:02:51 +1200 Subject: bitmap: extend comment to bitmap_print_bitmask/list_to_buf Extend comment to new function to warn potential users about caveats. Signed-off-by: Yury Norov Signed-off-by: Barry Song Link: https://lore.kernel.org/r/20210806110251.560-6-song.bao.hua@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- lib/bitmap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/bitmap.c b/lib/bitmap.c index 73746d96af81..663dd81967d4 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -568,6 +568,24 @@ static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp, * and it can break the size limit of converted decimal list and hexadecimal * bitmask. * + * WARNING! + * + * This function is not a replacement for sprintf() or bitmap_print_to_pagebuf(). + * It is intended to workaround sysfs limitations discussed above and should be + * used carefully in general case for the following reasons: + * - Time complexity is O(nbits^2/count), comparing to O(nbits) for snprintf(). + * - Memory complexity is O(nbits), comparing to O(1) for snprintf(). + * - @off and @count are NOT offset and number of bits to print. + * - If printing part of bitmap as list, the resulting string is not a correct + * list representation of bitmap. Particularly, some bits within or out of + * related interval may be erroneously set or unset. The format of the string + * may be broken, so bitmap_parselist-like parser may fail parsing it. + * - If printing the whole bitmap as list by parts, user must ensure the order + * of calls of the function such that the offset is incremented linearly. + * - If printing the whole bitmap as list by parts, user must keep bitmap + * unchanged between the very first and very last call. Otherwise concatenated + * result may be incorrect, and format may be broken. + * * Returns the number of characters actually printed to @buf */ int bitmap_print_bitmask_to_buf(char *buf, const unsigned long *maskp, -- cgit v1.2.1 From 6d6e03dbe5eff2044e0ae32acbf8b5dad6efb045 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 17 Aug 2021 13:24:48 +0300 Subject: ARM: tegra: paz00: Handle device properties with software node API The old device property API is going to be removed. Replacing the device_add_properties() call with the software node API equivalent, device_create_managed_software_node(). Reviewed-by: Andy Shevchenko Acked-by: Thierry Reding Signed-off-by: Heikki Krogerus Link: https://lore.kernel.org/r/20210817102449.39994-2-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-tegra/board-paz00.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index b5c990a7a5af..18d37f90cdfe 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -36,7 +36,7 @@ static struct gpiod_lookup_table wifi_gpio_lookup = { void __init tegra_paz00_wifikill_init(void) { - platform_device_add_properties(&wifi_rfkill_device, wifi_rfkill_prop); + device_create_managed_software_node(&wifi_rfkill_device.dev, wifi_rfkill_prop, NULL); gpiod_add_lookup_table(&wifi_gpio_lookup); platform_device_register(&wifi_rfkill_device); } -- cgit v1.2.1 From bd1e336aa8535a99f339e2d66a611984262221ce Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 17 Aug 2021 13:24:49 +0300 Subject: driver core: platform: Remove platform_device_add_properties() There are no more users for it. The last place where it's called is in platform_device_register_full(). Replacing that call with device_create_managed_software_node() and removing the function. Reviewed-by: Andy Shevchenko Reviewed-by: Thierry Reding Signed-off-by: Heikki Krogerus Link: https://lore.kernel.org/r/20210817102449.39994-3-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 20 ++------------------ include/linux/platform_device.h | 2 -- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index a94b7f454881..652531f67135 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -641,22 +641,6 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, } EXPORT_SYMBOL_GPL(platform_device_add_data); -/** - * platform_device_add_properties - add built-in properties to a platform device - * @pdev: platform device to add properties to - * @properties: null terminated array of properties to add - * - * The function will take deep copy of @properties and attach the copy to the - * platform device. The memory associated with properties will be freed when the - * platform device is released. - */ -int platform_device_add_properties(struct platform_device *pdev, - const struct property_entry *properties) -{ - return device_add_properties(&pdev->dev, properties); -} -EXPORT_SYMBOL_GPL(platform_device_add_properties); - /** * platform_device_add - add a platform device to device hierarchy * @pdev: platform device we're adding @@ -842,8 +826,8 @@ struct platform_device *platform_device_register_full( goto err; if (pdevinfo->properties) { - ret = platform_device_add_properties(pdev, - pdevinfo->properties); + ret = device_create_managed_software_node(&pdev->dev, + pdevinfo->properties, NULL); if (ret) goto err; } diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index ed42ea9f60ba..7c96f169d274 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -197,8 +197,6 @@ extern int platform_device_add_resources(struct platform_device *pdev, unsigned int num); extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size); -extern int platform_device_add_properties(struct platform_device *pdev, - const struct property_entry *properties); extern int platform_device_add(struct platform_device *pdev); extern void platform_device_del(struct platform_device *pdev); extern void platform_device_put(struct platform_device *pdev); -- cgit v1.2.1 From 049d1693db78144c979b34e2084287ada912cf7f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 26 Aug 2021 11:13:43 +0200 Subject: MAINTAINERS: Add dri-devel for component.[hc] dri-devel is the main user, and somehow there's been the assumption that component stuff is unmaintained. Cc: Ezequiel Garcia Cc: "Rafael J. Wysocki" Signed-off-by: Daniel Vetter References: https://lore.kernel.org/dri-devel/CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com/ Link: https://lore.kernel.org/r/20210826091343.1039763-1-daniel.vetter@ffwll.ch Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c9467d2839f5..b227a96e543e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5707,6 +5707,11 @@ F: Documentation/admin-guide/blockdev/ F: drivers/block/drbd/ F: lib/lru_cache.c +DRIVER COMPONENT FRAMEWORK +L: dri-devel@lists.freedesktop.org +F: drivers/base/component.c +F: include/linux/component.h + DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS M: Greg Kroah-Hartman R: "Rafael J. Wysocki" -- cgit v1.2.1