[PATCH v6] drm/drv: Convert wedged event string building to seq_buf
Mallesh Koujalagi <[email protected]>
| Newsgroups | org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <[email protected]> |
event_string[] has a fixed size of WEDGE_STR_LEN (32) bytes. The original scnprintf()-based loop required a manual pre-flight bounds check. Replace the manual bookkeeping with seq_buf, which tracks overflow internally. seq_buf_printf() writes each "method," token into the buffer. On overflow, a warning is issued, len retains the position of the last successful write, so the trailing comma is stripped cleanly without including any partial method name in the uevent payload. Assisted-by: Claude:claude-Sonnet-4.6 Signed-off-by: Mallesh Koujalagi <[email protected]> --- v2: - Add proper logic to handle recovery string. (Raag) v3: - Convert manual bounds check to seq_buf. (Jani Nikula) - Use drm_WARN_ONCE() instead of drm_WARN_ON() for overflow. (Raag) v4: - Use DECLARE_SEQ_BUF. (Jani) - Warn overflow at end of loop. v5: - Check and warn overflow inside loop. (Raag) v6: - Rebase. - Drop fix. (Raag) --- drivers/gpu/drm/drm_drv.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index cb53baa70995..8c0879c336e5 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -36,6 +36,7 @@ #include <linux/mount.h> #include <linux/pseudo_fs.h> #include <linux/sched.h> +#include <linux/seq_buf.h> #include <linux/slab.h> #include <linux/sprintf.h> #include <linux/srcu.h> @@ -576,27 +577,31 @@ static const char *drm_get_wedge_recovery(unsigned int opt) int drm_dev_wedged_event(struct drm_device *dev, unsigned long method, struct drm_wedge_task_info *info) { - char event_string[WEDGE_STR_LEN], pid_string[PID_STR_LEN], comm_string[COMM_STR_LEN]; - char *envp[] = { event_string, NULL, NULL, NULL }; - const char *recovery = NULL; - unsigned int len, opt; + DECLARE_SEQ_BUF(event_string, WEDGE_STR_LEN); + char pid_string[PID_STR_LEN], comm_string[COMM_STR_LEN]; + char *envp[4] = { }; + unsigned int len = 0, opt; - len = scnprintf(event_string, sizeof(event_string), "%s", "WEDGED="); + seq_buf_puts(&event_string, "WEDGED="); + envp[0] = event_string.buffer; for_each_set_bit(opt, &method, BITS_PER_TYPE(method)) { - recovery = drm_get_wedge_recovery(opt); + const char *recovery = drm_get_wedge_recovery(opt); if (drm_WARN_ONCE(dev, !recovery, "invalid recovery method %u\n", opt)) break; - len += scnprintf(event_string + len, sizeof(event_string) - len, "%s,", recovery); + if (drm_WARN_ON_ONCE(dev, seq_buf_printf(&event_string, "%s,", recovery))) + break; + + len = seq_buf_used(&event_string); } - if (recovery) - /* Get rid of trailing comma */ - event_string[len - 1] = '\0'; + if (len) + /* Strip trailing comma; also discards any partial overflow entry */ + event_string.buffer[len - 1] = '\0'; else - /* Caller is unsure about recovery, do the best we can at this point. */ - snprintf(event_string, sizeof(event_string), "%s", "WEDGED=unknown"); + /* No complete entry written, do the best we can at this point. */ + snprintf(event_string.buffer, event_string.size, "%s", "WEDGED=unknown"); drm_info(dev, "device wedged, %s\n", method == DRM_WEDGE_RECOVERY_NONE ? "but no recovery needed" : "needs recovery"); -- 2.48.1