All of lore.kernel.org
 help / color / mirror / Atom feed
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


  parent reply	other threads:[~2026-10-01 22:04 UTC|newest]

Thread overview: 11+ 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-02 20:45   ` Ruhl, Michael J
2026-10-01 22:03 ` David E. Box [this message]
2026-10-02  9:13   ` [PATCH 3/3] platform/x86/intel/pmt: Notify userspace when crashlogs complete sashiko-bot
2026-10-02 20:59   ` Ruhl, Michael J
2026-10-01 22:11 ` ✗ CI.checkpatch: warning for platform/x86/intel/pmt: Fix crashlog regressions and add completion uevent Patchwork
2026-10-01 22:13 ` ✓ CI.KUnit: success " Patchwork
2026-10-12 15:54 ` [PATCH 0/3] " Ilpo Järvinen

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.