Commit 3b9c181b authored by José Roberto de Souza's avatar José Roberto de Souza Committed by Rodrigo Vivi

devcoredump: Add dev_coredumpm_timeout()

Add function to set a custom coredump timeout.

For Xe driver usage, current 5 minutes timeout may be too short for
users to search and understand what needs to be done to capture
coredump to report bugs.

We have plans to automate(distribute a udev script) it but at the end
will be up to distros and users to pack it so having a option to
increase the timeout is a safer option.

v2:
- replace dev_coredump_timeout_set() by dev_coredumpm_timeout() (Mukesh)

v3:
- make dev_coredumpm() static inline (Johannes)

v5:
- rename DEVCOREDUMP_TIMEOUT -> DEVCD_TIMEOUT to avoid redefinition
in include/net/bluetooth/coredump.h

v6:
- fix definition of dev_coredumpm_timeout() when CONFIG_DEV_COREDUMP
is disabled

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Mukesh Ojha <quic_mojha@quicinc.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: Jonathan Cavitt <jonathan.cavitt@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: default avatarJonathan Cavitt <jonathan.cavitt@intel.com>
Signed-off-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20240611174716.72660-1-jose.souza@intel.comSigned-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent 513ea833
...@@ -18,9 +18,6 @@ static struct class devcd_class; ...@@ -18,9 +18,6 @@ static struct class devcd_class;
/* global disable flag, for security purposes */ /* global disable flag, for security purposes */
static bool devcd_disabled; static bool devcd_disabled;
/* if data isn't read by userspace after 5 minutes then delete it */
#define DEVCD_TIMEOUT (HZ * 60 * 5)
struct devcd_entry { struct devcd_entry {
struct device devcd_dev; struct device devcd_dev;
void *data; void *data;
...@@ -328,7 +325,8 @@ void dev_coredump_put(struct device *dev) ...@@ -328,7 +325,8 @@ void dev_coredump_put(struct device *dev)
EXPORT_SYMBOL_GPL(dev_coredump_put); EXPORT_SYMBOL_GPL(dev_coredump_put);
/** /**
* dev_coredumpm - create device coredump with read/free methods * dev_coredumpm_timeout - create device coredump with read/free methods with a
* custom timeout.
* @dev: the struct device for the crashed device * @dev: the struct device for the crashed device
* @owner: the module that contains the read/free functions, use %THIS_MODULE * @owner: the module that contains the read/free functions, use %THIS_MODULE
* @data: data cookie for the @read/@free functions * @data: data cookie for the @read/@free functions
...@@ -336,17 +334,20 @@ EXPORT_SYMBOL_GPL(dev_coredump_put); ...@@ -336,17 +334,20 @@ EXPORT_SYMBOL_GPL(dev_coredump_put);
* @gfp: allocation flags * @gfp: allocation flags
* @read: function to read from the given buffer * @read: function to read from the given buffer
* @free: function to free the given buffer * @free: function to free the given buffer
* @timeout: time in jiffies to remove coredump
* *
* Creates a new device coredump for the given device. If a previous one hasn't * Creates a new device coredump for the given device. If a previous one hasn't
* been read yet, the new coredump is discarded. The data lifetime is determined * been read yet, the new coredump is discarded. The data lifetime is determined
* by the device coredump framework and when it is no longer needed the @free * by the device coredump framework and when it is no longer needed the @free
* function will be called to free the data. * function will be called to free the data.
*/ */
void dev_coredumpm(struct device *dev, struct module *owner, void dev_coredumpm_timeout(struct device *dev, struct module *owner,
void *data, size_t datalen, gfp_t gfp, void *data, size_t datalen, gfp_t gfp,
ssize_t (*read)(char *buffer, loff_t offset, size_t count, ssize_t (*read)(char *buffer, loff_t offset,
void *data, size_t datalen), size_t count, void *data,
void (*free)(void *data)) size_t datalen),
void (*free)(void *data),
unsigned long timeout)
{ {
static atomic_t devcd_count = ATOMIC_INIT(0); static atomic_t devcd_count = ATOMIC_INIT(0);
struct devcd_entry *devcd; struct devcd_entry *devcd;
...@@ -403,7 +404,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, ...@@ -403,7 +404,7 @@ void dev_coredumpm(struct device *dev, struct module *owner,
dev_set_uevent_suppress(&devcd->devcd_dev, false); dev_set_uevent_suppress(&devcd->devcd_dev, false);
kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD);
INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); INIT_DELAYED_WORK(&devcd->del_wk, devcd_del);
schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); schedule_delayed_work(&devcd->del_wk, timeout);
mutex_unlock(&devcd->mutex); mutex_unlock(&devcd->mutex);
return; return;
put_device: put_device:
...@@ -414,7 +415,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, ...@@ -414,7 +415,7 @@ void dev_coredumpm(struct device *dev, struct module *owner,
free: free:
free(data); free(data);
} }
EXPORT_SYMBOL_GPL(dev_coredumpm); EXPORT_SYMBOL_GPL(dev_coredumpm_timeout);
/** /**
* dev_coredumpsg - create device coredump that uses scatterlist as data * dev_coredumpsg - create device coredump that uses scatterlist as data
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
/* if data isn't read by userspace after 5 minutes then delete it */
#define DEVCD_TIMEOUT (HZ * 60 * 5)
/* /*
* _devcd_free_sgtable - free all the memory of the given scatterlist table * _devcd_free_sgtable - free all the memory of the given scatterlist table
* (i.e. both pages and scatterlist instances) * (i.e. both pages and scatterlist instances)
...@@ -50,16 +53,17 @@ static inline void _devcd_free_sgtable(struct scatterlist *table) ...@@ -50,16 +53,17 @@ static inline void _devcd_free_sgtable(struct scatterlist *table)
kfree(delete_iter); kfree(delete_iter);
} }
#ifdef CONFIG_DEV_COREDUMP #ifdef CONFIG_DEV_COREDUMP
void dev_coredumpv(struct device *dev, void *data, size_t datalen, void dev_coredumpv(struct device *dev, void *data, size_t datalen,
gfp_t gfp); gfp_t gfp);
void dev_coredumpm(struct device *dev, struct module *owner, void dev_coredumpm_timeout(struct device *dev, struct module *owner,
void *data, size_t datalen, gfp_t gfp, void *data, size_t datalen, gfp_t gfp,
ssize_t (*read)(char *buffer, loff_t offset, size_t count, ssize_t (*read)(char *buffer, loff_t offset,
void *data, size_t datalen), size_t count, void *data,
void (*free)(void *data)); size_t datalen),
void (*free)(void *data),
unsigned long timeout);
void dev_coredumpsg(struct device *dev, struct scatterlist *table, void dev_coredumpsg(struct device *dev, struct scatterlist *table,
size_t datalen, gfp_t gfp); size_t datalen, gfp_t gfp);
...@@ -73,11 +77,13 @@ static inline void dev_coredumpv(struct device *dev, void *data, ...@@ -73,11 +77,13 @@ static inline void dev_coredumpv(struct device *dev, void *data,
} }
static inline void static inline void
dev_coredumpm(struct device *dev, struct module *owner, dev_coredumpm_timeout(struct device *dev, struct module *owner,
void *data, size_t datalen, gfp_t gfp, void *data, size_t datalen, gfp_t gfp,
ssize_t (*read)(char *buffer, loff_t offset, size_t count, ssize_t (*read)(char *buffer, loff_t offset,
void *data, size_t datalen), size_t count, void *data,
void (*free)(void *data)) size_t datalen),
void (*free)(void *data),
unsigned long timeout)
{ {
free(data); free(data);
} }
...@@ -92,4 +98,29 @@ static inline void dev_coredump_put(struct device *dev) ...@@ -92,4 +98,29 @@ static inline void dev_coredump_put(struct device *dev)
} }
#endif /* CONFIG_DEV_COREDUMP */ #endif /* CONFIG_DEV_COREDUMP */
/**
* dev_coredumpm - create device coredump with read/free methods
* @dev: the struct device for the crashed device
* @owner: the module that contains the read/free functions, use %THIS_MODULE
* @data: data cookie for the @read/@free functions
* @datalen: length of the data
* @gfp: allocation flags
* @read: function to read from the given buffer
* @free: function to free the given buffer
*
* Creates a new device coredump for the given device. If a previous one hasn't
* been read yet, the new coredump is discarded. The data lifetime is determined
* by the device coredump framework and when it is no longer needed the @free
* function will be called to free the data.
*/
static inline void dev_coredumpm(struct device *dev, struct module *owner,
void *data, size_t datalen, gfp_t gfp,
ssize_t (*read)(char *buffer, loff_t offset, size_t count,
void *data, size_t datalen),
void (*free)(void *data))
{
dev_coredumpm_timeout(dev, owner, data, datalen, gfp, read, free,
DEVCD_TIMEOUT);
}
#endif /* __DEVCOREDUMP_H */ #endif /* __DEVCOREDUMP_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment