From: "David E. Box" <david.e.box@linux.intel.com>
To: ilpo.jarvinen@linux.intel.com, david.e.box@linux.intel.com,
linux-kernel@vger.kernel.org,
platform-driver-x86@vger.kernel.org, rodrigo.vivi@intel.com,
michael.j.ruhl@intel.com, ayaz.siddiqui@intel.com,
syed.abdul.muqthyar.ahmed@intel.com,
intel-xe@lists.freedesktop.org, hansg@kernel.org
Subject: [PATCH 3/3] platform/x86/intel/pmt: Notify userspace when crashlogs complete
Date: Thu, 1 Oct 2026 15:03:48 -0700 [thread overview]
Message-ID: <20261001220351.1592138-4-david.e.box@linux.intel.com> (raw)
In-Reply-To: <20261001220351.1592138-1-david.e.box@linux.intel.com>
A crashlog may already be complete when the driver binds, or it may
complete asynchronously after userspace requests a manual trigger.
Userspace otherwise has to poll to discover that data is ready.
Emit a KOBJ_CHANGE uevent on the per-instance crashlog device when a
completed log is found at probe. After a manual trigger, poll the
completion bit at 100 ms intervals for up to 5 seconds and emit the same
event when capture completes. The event carries two environment
variables:
INTEL_PMT_CRASHLOG_EVENT=PRESENT
INTEL_PMT_CRASHLOG_COMPLETE=1
Initialize the work items before the device's sysfs attributes are
exposed, and disable and drain them during removal.
Document the new uevent in the sysfs-class-intel_pmt ABI file.
Assisted-by: LLM
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
.../ABI/testing/sysfs-class-intel_pmt | 14 ++++
drivers/platform/x86/intel/pmt/crashlog.c | 84 ++++++++++++++++++-
2 files changed, 95 insertions(+), 3 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-intel_pmt b/Documentation/ABI/testing/sysfs-class-intel_pmt
index ed4c886a21b1..c0b0d123afdf 100644
--- a/Documentation/ABI/testing/sysfs-class-intel_pmt
+++ b/Documentation/ABI/testing/sysfs-class-intel_pmt
@@ -66,6 +66,20 @@ Description:
can be determined from an XML file of specified GUID for the
parent device.
+What: /sys/class/intel_pmt/crashlog<x>
+Date: October 2026
+KernelVersion: 7.4
+Contact: David Box <david.e.box@linux.intel.com>
+Description:
+ When a crashlog device is probed with a completed crashlog
+ already present, or a manual trigger completes, the driver emits
+ a KOBJ_CHANGE uevent for that crashlog<x> device.
+
+ The following uevent environment variables are added:
+
+ INTEL_PMT_CRASHLOG_EVENT=PRESENT
+ INTEL_PMT_CRASHLOG_COMPLETE=1
+
What: /sys/class/intel_pmt/crashlog<x>/crashlog
Date: October 2020
KernelVersion: 5.10
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index f936daf99e4d..21e8e2199bdc 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -12,12 +12,14 @@
#include <linux/cleanup.h>
#include <linux/intel_vsec.h>
#include <linux/kernel.h>
+#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/overflow.h>
+#include <linux/workqueue.h>
#include "class.h"
@@ -113,6 +115,9 @@ struct crashlog_entry {
struct intel_pmt_entry entry;
struct mutex control_mutex;
const struct crashlog_info *info;
+ struct work_struct uevent_work;
+ struct delayed_work uevent_poll_work;
+ u8 uevent_poll_tries;
};
struct pmt_crashlog_priv {
@@ -120,6 +125,9 @@ struct pmt_crashlog_priv {
struct crashlog_entry entry[];
};
+#define PMT_CRASHLOG_UEVENT_POLL_MS 100
+#define PMT_CRASHLOG_UEVENT_POLL_MAX_TRIES 50
+
/*
* I/O
*/
@@ -227,6 +235,47 @@ static void pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
pmt_crashlog_rmw(crashlog, crashlog->info->control.rearm, true);
}
+static void pmt_crashlog_uevent_fn(struct work_struct *work)
+{
+ struct crashlog_entry *crashlog =
+ container_of(work, struct crashlog_entry, uevent_work);
+ char *envp[] = {
+ "INTEL_PMT_CRASHLOG_EVENT=PRESENT",
+ "INTEL_PMT_CRASHLOG_COMPLETE=1",
+ NULL,
+ };
+
+ if (crashlog->entry.kobj)
+ kobject_uevent_env(crashlog->entry.kobj, KOBJ_CHANGE, envp);
+}
+
+static void pmt_crashlog_uevent_poll_fn(struct work_struct *work)
+{
+ struct crashlog_entry *crashlog =
+ container_of(to_delayed_work(work), struct crashlog_entry,
+ uevent_poll_work);
+ guard(mutex)(&crashlog->control_mutex);
+
+ /* A newer trigger_store() re-armed us; that cycle owns the notification */
+ if (delayed_work_pending(&crashlog->uevent_poll_work))
+ return;
+
+ if (pmt_crashlog_complete(crashlog)) {
+ schedule_work(&crashlog->uevent_work);
+ return;
+ }
+
+ if (++crashlog->uevent_poll_tries < PMT_CRASHLOG_UEVENT_POLL_MAX_TRIES)
+ schedule_delayed_work(&crashlog->uevent_poll_work,
+ msecs_to_jiffies(PMT_CRASHLOG_UEVENT_POLL_MS));
+}
+
+static void pmt_crashlog_notify_pending(struct crashlog_entry *crashlog)
+{
+ if (pmt_crashlog_complete(crashlog))
+ schedule_work(&crashlog->uevent_work);
+}
+
/*
* sysfs
*/
@@ -423,7 +472,19 @@ trigger_store(struct device *dev, struct device_attribute *attr,
if (pmt_crashlog_complete(crashlog))
return -EEXIST;
+ /*
+ * Only now are we actually starting a fresh crash: any stale poll
+ * cycle left over from a prior trigger can be dropped safely, since
+ * pmt_crashlog_complete() above proved it carried no unresolved
+ * completion. Non-sync: uevent_poll_fn() takes this same mutex, so
+ * cancel_delayed_work_sync() here could deadlock against it.
+ */
+ cancel_delayed_work(&crashlog->uevent_poll_work);
+
pmt_crashlog_set_execute(crashlog);
+ crashlog->uevent_poll_tries = 0;
+ schedule_delayed_work(&crashlog->uevent_poll_work,
+ msecs_to_jiffies(PMT_CRASHLOG_UEVENT_POLL_MS));
return count;
}
@@ -551,6 +612,9 @@ static void pmt_crashlog_remove(struct auxiliary_device *auxdev)
for (i = 0; i < priv->num_entries; i++) {
struct crashlog_entry *crashlog = &priv->entry[i];
+ /* Disable, not cancel: a racing trigger_store() must not re-arm */
+ disable_delayed_work_sync(&crashlog->uevent_poll_work);
+ disable_work_sync(&crashlog->uevent_work);
intel_pmt_dev_destroy(&crashlog->entry, &pmt_crashlog_ns);
mutex_destroy(&crashlog->control_mutex);
}
@@ -572,15 +636,29 @@ static int pmt_crashlog_probe(struct auxiliary_device *auxdev,
auxiliary_set_drvdata(auxdev, priv);
for (i = 0; i < intel_vsec_dev->num_resources; i++) {
- struct intel_pmt_entry *entry = &priv->entry[priv->num_entries].entry;
+ struct crashlog_entry *crashlog = &priv->entry[priv->num_entries];
+ struct intel_pmt_entry *entry = &crashlog->entry;
+
+ /* init before dev_create() exposes trigger sysfs to userspace */
+ INIT_WORK(&crashlog->uevent_work, pmt_crashlog_uevent_fn);
+ INIT_DELAYED_WORK(&crashlog->uevent_poll_work,
+ pmt_crashlog_uevent_poll_fn);
+ crashlog->uevent_poll_tries = 0;
ret = intel_pmt_dev_create(entry, &pmt_crashlog_ns, intel_vsec_dev, i);
- if (ret < 0)
+ if (ret < 0) {
+ cancel_delayed_work_sync(&crashlog->uevent_poll_work);
+ cancel_work_sync(&crashlog->uevent_work);
goto abort_probe;
- if (ret)
+ }
+ if (ret) {
+ cancel_delayed_work_sync(&crashlog->uevent_poll_work);
+ cancel_work_sync(&crashlog->uevent_work);
continue;
+ }
priv->num_entries++;
+ pmt_crashlog_notify_pending(crashlog);
}
return 0;
--
2.43.0
prev parent reply other threads:[~2026-10-01 22:04 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 22:03 [PATCH 0/3] platform/x86/intel/pmt: Fix crashlog regressions and add completion uevent David E. Box
2026-10-01 22:03 ` [PATCH 1/3] platform/x86/intel/pmt: Fix NULL dereference when reading crashlog data David E. Box
2026-10-02 12:43 ` Ruhl, Michael J
2026-10-01 22:03 ` [PATCH 2/3] platform/x86/intel/vsec: Fix inverted walk_header() test in get_features() David E. Box
2026-10-01 22:03 ` David E. Box [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261001220351.1592138-4-david.e.box@linux.intel.com \
--to=david.e.box@linux.intel.com \
--cc=ayaz.siddiqui@intel.com \
--cc=hansg@kernel.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.j.ruhl@intel.com \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rodrigo.vivi@intel.com \
--cc=syed.abdul.muqthyar.ahmed@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®