LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Shivang Upadhyay <shivangu@linux.ibm.com>
To: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Cc: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com,
	chleroy@kernel.org, thuth@redhat.com,
	Shivang Upadhyay <shivangu@linux.ibm.com>,
	Aditya Gupta <adityag@linux.ibm.com>,
	Sourabh Jain <sourabhjain@linux.ibm.com>,
	Mahesh J Salgaonkar <mahesh@linux.ibm.com>
Subject: [PATCH] powerpc/powernv: Cache OPAL check_token() results
Date: Mon,  1 Jun 2026 16:55:20 +0530	[thread overview]
Message-ID: <20260601112520.161605-1-shivangu@linux.ibm.com> (raw)

Add a caching layer for the opal_check_token() OPAL call to avoid
repeated firmware calls for token availability checks.

The opal_check_token() function is used to determine if a specific
OPAL firmware call is supported on the current platform. This check
is performed frequently during boot and runtime, resulting in
unnecessary firmware calls for the same token values.

This reduces firmware call overhead during boot and runtime token
checks while maintaining compatibility with existing code.

Testing with buildroot images shows OPAL calls reduced from
35578 to 28983, before console bring-up.

Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <chleroy@kernel.org>
Cc: Aditya Gupta <adityag@linux.ibm.com>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
Cc: Mahesh J Salgaonkar <mahesh@linux.ibm.com>
Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com>
---
 arch/powerpc/include/asm/opal.h            |  1 +
 arch/powerpc/platforms/powernv/opal-call.c |  2 +-
 arch/powerpc/platforms/powernv/opal.c      | 55 ++++++++++++++++++++++
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 0a398265ba04..e7e11479122b 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -156,6 +156,7 @@ int64_t opal_pci_next_error(uint64_t phb_id, __be64 *first_frozen_pe,
 int64_t opal_pci_poll(uint64_t id);
 int64_t opal_return_cpu(void);
 int64_t opal_check_token(uint64_t token);
+int64_t opal_check_token_call(uint64_t token);
 int64_t opal_reinit_cpus(uint64_t flags);
 
 int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val);
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index 021b0ec29e24..00325c189e69 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -207,7 +207,7 @@ OPAL_CALL(opal_validate_flash,			OPAL_FLASH_VALIDATE);
 OPAL_CALL(opal_manage_flash,			OPAL_FLASH_MANAGE);
 OPAL_CALL(opal_update_flash,			OPAL_FLASH_UPDATE);
 OPAL_CALL(opal_resync_timebase,			OPAL_RESYNC_TIMEBASE);
-OPAL_CALL(opal_check_token,			OPAL_CHECK_TOKEN);
+OPAL_CALL(opal_check_token_call,		OPAL_CHECK_TOKEN);
 OPAL_CALL(opal_dump_init,			OPAL_DUMP_INIT);
 OPAL_CALL(opal_dump_info,			OPAL_DUMP_INFO);
 OPAL_CALL(opal_dump_info2,			OPAL_DUMP_INFO2);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 1946dbdc9fa1..c32035136efa 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -73,6 +73,12 @@ static struct task_struct *kopald_tsk;
 static struct opal_msg *opal_msg;
 static u32 opal_msg_size __ro_after_init;
 
+/* Token cache for opal_check_token() */
+#define OPAL_TOKEN_CACHE_SIZE 256  /* Covers tokens 0-255, including OPAL_LAST (178) */
+static unsigned long opal_token_cache[BITS_TO_LONGS(OPAL_TOKEN_CACHE_SIZE)] __ro_after_init;
+static bool opal_token_cache_initialized __ro_after_init;
+static void opal_token_cache_init(void);
+
 void __init opal_configure_cores(void)
 {
 	u64 reinit_flags = 0;
@@ -1125,8 +1131,57 @@ EXPORT_SYMBOL_GPL(opal_flash_read);
 EXPORT_SYMBOL_GPL(opal_flash_write);
 EXPORT_SYMBOL_GPL(opal_flash_erase);
 EXPORT_SYMBOL_GPL(opal_prd_msg);
+
+/**
+ * opal_check_token - Check if an OPAL call token is supported
+ * @token: OPAL token number to check
+ *
+ * Returns 1 if supported, 0 if not.
+ * Uses a cached bitmap for fast lookups after initialization.
+ */
+int64_t opal_check_token(uint64_t token)
+{
+	/* Initialize if not done before */
+	if (!opal_token_cache_initialized) {
+		opal_token_cache_init();
+	}
+
+	/* Use cached result */
+	if (token < OPAL_TOKEN_CACHE_SIZE) {
+		return test_bit(token, opal_token_cache);
+	}
+
+	/* Fall back to direct OPAL call for out-of-range tokens */
+	return opal_check_token_call(token);
+}
 EXPORT_SYMBOL_GPL(opal_check_token);
 
+/**
+ * opal_token_cache_init - Initialize the OPAL token cache
+ *
+ * Called during opal_init() to populate the token cache by querying
+ * OPAL firmware for all tokens in the supported range.
+ */
+static void opal_token_cache_init(void)
+{
+	uint64_t token;
+	int64_t result;
+
+	pr_debug("Initializing OPAL token cache\n");
+
+	/* Query OPAL for each token and cache the result */
+	for (token = 0; token < OPAL_TOKEN_CACHE_SIZE; token++) {
+		result = opal_check_token_call(token);
+		if (result == 1)
+			set_bit(token, opal_token_cache);
+	}
+
+	/* Mark cache as initialized - enables fast path */
+	opal_token_cache_initialized = true;
+
+	pr_info("OPAL token cache initialized\n");
+}
+
 /* Convert a region of vmalloc memory to an opal sg list */
 struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
 					     unsigned long vmalloc_size)
-- 
2.53.0



             reply	other threads:[~2026-06-01 11:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-01 11:25 Shivang Upadhyay [this message]
2026-06-03  3:52 ` [PATCH] powerpc/powernv: Cache OPAL check_token() results Sourabh Jain

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=20260601112520.161605-1-shivangu@linux.ibm.com \
    --to=shivangu@linux.ibm.com \
    --cc=adityag@linux.ibm.com \
    --cc=chleroy@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=maddy@linux.ibm.com \
    --cc=mahesh@linux.ibm.com \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=sourabhjain@linux.ibm.com \
    --cc=thuth@redhat.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