From: Deb McLemore <debmc@linux.vnet.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: jk@ozlabs.org, Deb McLemore <debmc@linux.vnet.ibm.com>
Subject: [PATCH] powerpc/powernv: Add queue mechanism for early messages
Date: Sun, 26 Nov 2017 08:30:15 -0600 [thread overview]
Message-ID: <1511706615-7126-1-git-send-email-debmc@linux.vnet.ibm.com> (raw)
Add a check for do_notify to confirm that a message handler
has been registered before an attempt is made to call notifier
call chain.
If the message handler has not been registered queue up the message
to be replayed when the proper registration is called.
Signed-off-by: Deb McLemore <debmc@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/opal.c | 88 +++++++++++++++++++++++++++++++++--
1 file changed, 83 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 65c79ec..0e3b464 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -40,6 +40,16 @@
#include "powernv.h"
+#define OPAL_MSG_QUEUE_MAX 16
+
+struct OpalMsgNode {
+ struct list_head opal_queue_list_node;
+ struct opal_msg msg;
+ uint32_t queue_msg_type;
+};
+
+static LIST_HEAD(opal_msg_queue_pending);
+
/* /sys/firmware/opal */
struct kobject *opal_kobj;
@@ -55,11 +65,15 @@ struct mcheck_recoverable_range {
u64 recover_addr;
};
+static unsigned long opal_msg_notify_reg_mask;
+static int opal_active_queue_elements;
+
static struct mcheck_recoverable_range *mc_recoverable_range;
static int mc_recoverable_range_len;
struct device_node *opal_node;
static DEFINE_SPINLOCK(opal_write_lock);
+static DEFINE_SPINLOCK(opal_msg_lock);
static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
static uint32_t opal_heartbeat;
static struct task_struct *kopald_tsk;
@@ -238,14 +252,47 @@ machine_early_initcall(powernv, opal_register_exception_handlers);
int opal_message_notifier_register(enum opal_msg_type msg_type,
struct notifier_block *nb)
{
+ struct OpalMsgNode *msg_node, *tmp;
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&opal_msg_lock, flags);
+
+ opal_msg_notify_reg_mask |= 1 << msg_type;
+
+ spin_unlock_irqrestore(&opal_msg_lock, flags);
+
if (!nb || msg_type >= OPAL_MSG_TYPE_MAX) {
pr_warning("%s: Invalid arguments, msg_type:%d\n",
__func__, msg_type);
return -EINVAL;
}
- return atomic_notifier_chain_register(
- &opal_msg_notifier_head[msg_type], nb);
+ ret = atomic_notifier_chain_register(
+ &opal_msg_notifier_head[msg_type], nb);
+
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&opal_msg_lock, flags);
+ list_for_each_entry_safe(msg_node,
+ tmp,
+ &opal_msg_queue_pending,
+ opal_queue_list_node) {
+ if (msg_node->queue_msg_type == msg_type) {
+ atomic_notifier_call_chain(
+ &opal_msg_notifier_head[msg_type],
+ msg_type,
+ &msg_node->msg);
+ list_del(&msg_node->opal_queue_list_node);
+ kfree(msg_node);
+ opal_active_queue_elements--;
+ }
+ }
+ spin_unlock_irqrestore(&opal_msg_lock, flags);
+
+ return ret;
+
}
EXPORT_SYMBOL_GPL(opal_message_notifier_register);
@@ -259,9 +306,40 @@ EXPORT_SYMBOL_GPL(opal_message_notifier_unregister);
static void opal_message_do_notify(uint32_t msg_type, void *msg)
{
- /* notify subscribers */
- atomic_notifier_call_chain(&opal_msg_notifier_head[msg_type],
- msg_type, msg);
+ struct OpalMsgNode *msg_node;
+
+ unsigned long flags;
+
+ spin_lock_irqsave(&opal_msg_lock, flags);
+
+ if (opal_msg_notify_reg_mask & (1 << msg_type)) {
+ /* notify subscribers */
+ atomic_notifier_call_chain(&opal_msg_notifier_head[msg_type],
+ msg_type, msg);
+ } else {
+ if (opal_active_queue_elements < OPAL_MSG_QUEUE_MAX) {
+ msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC);
+ if (msg_node) {
+ INIT_LIST_HEAD(&msg_node->opal_queue_list_node);
+ memcpy(&msg_node->msg,
+ msg,
+ sizeof(struct opal_msg));
+ msg_node->queue_msg_type = msg_type;
+ list_add_tail(&msg_node->opal_queue_list_node,
+ &opal_msg_queue_pending);
+ opal_active_queue_elements++;
+ }
+ }
+
+ if (opal_active_queue_elements >= OPAL_MSG_QUEUE_MAX) {
+ pr_warn_once("%s: Notifier Register Queue full at %i\n",
+ __func__,
+ opal_active_queue_elements);
+ }
+ }
+
+ spin_unlock_irqrestore(&opal_msg_lock, flags);
+
}
static void opal_handle_message(void)
--
2.7.4
next reply other threads:[~2017-11-26 14:30 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-26 14:30 Deb McLemore [this message]
2017-11-28 13:30 ` [PATCH] powerpc/powernv: Add queue mechanism for early messages Michael Ellerman
2017-11-28 15:29 ` Deb McLemore
2017-11-29 21:05 ` [PATCH v2] " Deb McLemore
2018-05-16 13:35 ` Michael Ellerman
2018-05-21 2:04 ` [PATCH v3] " Deb McLemore
2019-10-30 12:14 ` Michael Ellerman
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=1511706615-7126-1-git-send-email-debmc@linux.vnet.ibm.com \
--to=debmc@linux.vnet.ibm.com \
--cc=jk@ozlabs.org \
--cc=linuxppc-dev@lists.ozlabs.org \
/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;
as well as URLs for NNTP newsgroup(s).