* [PATCH V3 1/3] sysfs: add attribute specification for /sysfs/devices/.../coredump
2018-01-11 8:36 [PATCH V3 0/3] sysfs: allow user-space request for devcoredump Arend van Spriel
@ 2018-01-11 8:36 ` Arend van Spriel
2018-01-11 8:36 ` [PATCH V3 2/3] drivers: base: add coredump driver ops Arend van Spriel
2018-01-11 8:36 ` [RFC V2 3/3] brcmfmac: pcie: implement .coredump() driver callback Arend van Spriel
2 siblings, 0 replies; 4+ messages in thread
From: Arend van Spriel @ 2018-01-11 8:36 UTC (permalink / raw)
To: Greg Koah Hartmann; +Cc: LKML, Arend van Spriel
This patch adds the specification for /sysfs/devices/.../coredump
which allows user-space to trigger a device coredump obtaining
binary data from the device for (fault) analysis. It relies on
CONFIG_DEV_COREDUMP being enabled.
Signed-off-by: Arend van Spriel <aspriel@gmail.com>
---
V2:
- no changes.
V3:
- changed contact to my gmail account.
---
Documentation/ABI/testing/sysfs-devices-coredump | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-devices-coredump
diff --git a/Documentation/ABI/testing/sysfs-devices-coredump b/Documentation/ABI/testing/sysfs-devices-coredump
new file mode 100644
index 0000000..e459368
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-coredump
@@ -0,0 +1,10 @@
+What: /sys/devices/.../coredump
+Date: December 2017
+Contact: Arend van Spriel <aspriel@gmail.com>
+Description:
+ The /sys/devices/.../coredump attribute is only present when the
+ device is bound to a driver, which provides the .coredump()
+ callback. The attribute is write only. Anything written to this
+ file will trigger the .coredump() callback.
+
+ Available when CONFIG_DEV_COREDUMP is enabled.
--
1.9.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH V3 2/3] drivers: base: add coredump driver ops
2018-01-11 8:36 [PATCH V3 0/3] sysfs: allow user-space request for devcoredump Arend van Spriel
2018-01-11 8:36 ` [PATCH V3 1/3] sysfs: add attribute specification for /sysfs/devices/.../coredump Arend van Spriel
@ 2018-01-11 8:36 ` Arend van Spriel
2018-01-11 8:36 ` [RFC V2 3/3] brcmfmac: pcie: implement .coredump() driver callback Arend van Spriel
2 siblings, 0 replies; 4+ messages in thread
From: Arend van Spriel @ 2018-01-11 8:36 UTC (permalink / raw)
To: Greg Koah Hartmann; +Cc: LKML, Arend van Spriel
This adds the coredump driver operation. When the driver defines it
a coredump file is added in the sysfs folder of the device upon
driver binding. The file is removed when the driver is unbound.
User-space can trigger a coredump for this device by echo'ing to
the coredump file.
Signed-off-by: Arend van Spriel <aspriel@gmail.com>
---
V2:
- extended the commit message.
V3:
- no changes.
---
drivers/base/dd.c | 40 +++++++++++++++++++++++++++++++++-------
include/linux/device.h | 2 +-
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 533c82f..de6fd09 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -288,6 +288,18 @@ static void driver_bound(struct device *dev)
kobject_uevent(&dev->kobj, KOBJ_BIND);
}
+static ssize_t coredump_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ device_lock(dev);
+ if (dev->driver->coredump)
+ dev->driver->coredump(dev);
+ device_unlock(dev);
+
+ return count;
+}
+static DEVICE_ATTR_WO(coredump);
+
static int driver_sysfs_add(struct device *dev)
{
int ret;
@@ -297,14 +309,26 @@ static int driver_sysfs_add(struct device *dev)
BUS_NOTIFY_BIND_DRIVER, dev);
ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
+ kobject_name(&dev->kobj));
+ if (ret)
+ goto fail;
+
+ ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj,
+ "driver");
+ if (ret)
+ goto rm_dev;
+
+ if (!IS_ENABLED(CONFIG_DEV_COREDUMP) || !dev->driver->coredump ||
+ !device_create_file(dev, &dev_attr_coredump))
+ return 0;
+
+ sysfs_remove_link(&dev->kobj, "driver");
+
+rm_dev:
+ sysfs_remove_link(&dev->driver->p->kobj,
kobject_name(&dev->kobj));
- if (ret == 0) {
- ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj,
- "driver");
- if (ret)
- sysfs_remove_link(&dev->driver->p->kobj,
- kobject_name(&dev->kobj));
- }
+
+fail:
return ret;
}
@@ -313,6 +337,8 @@ static void driver_sysfs_remove(struct device *dev)
struct device_driver *drv = dev->driver;
if (drv) {
+ if (drv->coredump)
+ device_remove_file(dev, &dev_attr_coredump);
sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
sysfs_remove_link(&dev->kobj, "driver");
}
diff --git a/include/linux/device.h b/include/linux/device.h
index 46cece5..cd3b47e 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -287,6 +287,7 @@ struct device_driver {
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
+ int (*coredump) (struct device *dev);
struct driver_private *p;
};
@@ -300,7 +301,6 @@ extern struct device_driver *driver_find(const char *name,
extern int driver_probe_done(void);
extern void wait_for_device_probe(void);
-
/* sysfs interface for exporting driver attributes */
struct driver_attribute {
--
1.9.1
^ permalink raw reply [flat|nested] 4+ messages in thread* [RFC V2 3/3] brcmfmac: pcie: implement .coredump() driver callback
2018-01-11 8:36 [PATCH V3 0/3] sysfs: allow user-space request for devcoredump Arend van Spriel
2018-01-11 8:36 ` [PATCH V3 1/3] sysfs: add attribute specification for /sysfs/devices/.../coredump Arend van Spriel
2018-01-11 8:36 ` [PATCH V3 2/3] drivers: base: add coredump driver ops Arend van Spriel
@ 2018-01-11 8:36 ` Arend van Spriel
2 siblings, 0 replies; 4+ messages in thread
From: Arend van Spriel @ 2018-01-11 8:36 UTC (permalink / raw)
To: Greg Koah Hartmann; +Cc: LKML, Arend van Spriel
This implements the .coredump() driver callback obtaining binary data
from the device and using devcoredump function to expose it in sysfs.
Signed-off-by: Arend van Spriel <aspriel@gmail.com>
---
V2:
- no changes
---
.../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 3c87157..55d0d25 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/bcma/bcma.h>
#include <linux/sched.h>
+#include <linux/devcoredump.h>
#include <asm/unaligned.h>
#include <soc.h>
@@ -1744,6 +1745,26 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
device_release_driver(dev);
}
+static int brcmf_pcie_dev_coredump(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
+ size_t len;
+ void *dump;
+
+ len = devinfo->ci->ramsize - devinfo->ci->srsize;
+ dump = vzalloc(len);
+ if (!dump)
+ return -ENOMEM;
+
+ brcmf_dbg(PCIE, "dump at 0x%08X: len=%zu\n", devinfo->ci->rambase, len);
+ brcmf_pcie_copy_dev_tomem(devinfo, devinfo->ci->rambase, dump, len);
+
+ dev_coredumpv(dev, dump, len, GFP_KERNEL);
+ return 0;
+}
+
static int
brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
@@ -2002,6 +2023,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
.id_table = brcmf_pcie_devid_table,
.probe = brcmf_pcie_probe,
.remove = brcmf_pcie_remove,
+ .driver.coredump = brcmf_pcie_dev_coredump,
#ifdef CONFIG_PM
.driver.pm = &brcmf_pciedrvr_pm,
#endif
--
1.9.1
^ permalink raw reply [flat|nested] 4+ messages in thread