[Skiboot] [PATCH 2/7] core/stack: Define a backtrace metadata struct

Andrew Donnellan andrew.donnellan at au1.ibm.com
Mon Mar 18 15:28:55 AEDT 2019


Every time we take a backtrace, we have to store the number of entries, the
OPAL API token, r1 caller and PIR values. Rather than defining these and
passing them around all over the place, let's throw them in a struct.

Define a struct, struct bt_metadata, to store these details, and convert
___backtrace() and ___print_backtrace() to use it.

We change the wrapper functions __backtrace() and __print_backtrace() to
call ___backtrace()/___print_backtrace() with struct bt_metadata, but don't
change their parameter profiles for now - we'll do that later.

Signed-off-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
---
 core/stack.c    | 53 ++++++++++++++++++++++++++---------------------------
 include/stack.h | 40 ++++++++++++++++++++++++++++------------
 2 files changed, 54 insertions(+), 39 deletions(-)

diff --git a/core/stack.c b/core/stack.c
index 5e4cf4bc0c53..773d91e34eea 100644
--- a/core/stack.c
+++ b/core/stack.c
@@ -27,10 +27,9 @@
 static struct bt_entry bt_buf[STACK_BUF_ENTRIES];
 
 /* Dumps backtrace to buffer */
-void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
-				unsigned long *token, unsigned long *r1_caller)
+void __nomcount ___backtrace(struct bt_entry *entries, unsigned int max_ents,
+			     struct bt_metadata *metadata)
 {
-	unsigned int room = *count;
 	unsigned long *fp = __builtin_frame_address(0);
 	unsigned long top_adj = top_of_ram;
 	struct stack_frame *eframe = (struct stack_frame *)fp;
@@ -39,8 +38,8 @@ void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
 	if (top_of_ram == SKIBOOT_BASE + SKIBOOT_SIZE)
 		top_adj = top_of_ram + STACK_SIZE;
 
-	*count = 0;
-	while(room) {
+	metadata->ents = 0;
+	while (max_ents) {
 		fp = (unsigned long *)fp[0];
 		if (!fp || (unsigned long)fp > top_adj)
 			break;
@@ -48,22 +47,20 @@ void __nomcount ___backtrace(struct bt_entry *entries, unsigned int *count,
 		entries->sp = (unsigned long)fp;
 		entries->pc = fp[2];
 		entries++;
-		*count = (*count) + 1;
-		room--;
+		metadata->ents++;
+		max_ents--;
 	}
 
-	*r1_caller = eframe->gpr[1];
+	metadata->r1_caller = eframe->gpr[1];
 
 	if (fp)
-		*token = eframe->gpr[0];
+		metadata->token = eframe->gpr[0];
 	else
-		*token = -1UL;
+		metadata->token = -1UL;
 }
 
-void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
-			      unsigned int count, unsigned long token,
-			      unsigned long r1_caller, char *out_buf,
-			      unsigned int *len, bool symbols)
+void ___print_backtrace(struct bt_entry *entries, struct bt_metadata *metadata,
+			char *out_buf, unsigned int *len, bool symbols)
 {
 	static char bt_text_buf[4096];
 	int i, l = 0, max;
@@ -77,14 +74,14 @@ void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
 	} else
 		max = *len - 1;
 
-	bottom = cpu_stack_bottom(pir);
-	normal_top = cpu_stack_top(pir);
-	top = cpu_emergency_stack_top(pir);
+	bottom = cpu_stack_bottom(metadata->pir);
+	normal_top = cpu_stack_top(metadata->pir);
+	top = cpu_emergency_stack_top(metadata->pir);
 	tbot = SKIBOOT_BASE;
 	ttop = (unsigned long)&_etext;
 
-	l += snprintf(buf, max, "CPU %04x Backtrace:\n", pir);
-	for (i = 0; i < count && l < max; i++) {
+	l += snprintf(buf, max, "CPU %04lx Backtrace:\n", metadata->pir);
+	for (i = 0; i < metadata->ents && l < max; i++) {
 		if (entries->sp < bottom || entries->sp > top)
 			mark = '!';
 		else if (entries->sp > normal_top)
@@ -101,9 +98,11 @@ void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
 		l += snprintf(buf + l, max - l, "\n");
 		entries++;
 	}
-	if (token <= OPAL_LAST)
-		l += snprintf(buf + l, max - l, " --- OPAL call token: 0x%lx caller R1: 0x%016lx ---\n", token, r1_caller);
-	else if (token == -1UL)
+	if (metadata->token <= OPAL_LAST)
+		l += snprintf(buf + l, max - l,
+			      " --- OPAL call token: 0x%lx caller R1: 0x%016lx ---\n",
+			      metadata->token, metadata->r1_caller);
+	else if (metadata->token == -1UL)
 		l += snprintf(buf + l, max - l, " --- OPAL boot ---\n");
 	if (!out_buf)
 		write(stdout->fd, bt_text_buf, l);
@@ -122,14 +121,14 @@ struct lock bt_lock = LOCK_UNLOCKED;
 
 void backtrace(void)
 {
-	unsigned int ents = STACK_BUF_ENTRIES;
-	unsigned long token, r1_caller;
+	struct bt_metadata metadata = {
+		.pir = mfspr(SPR_PIR),
+	};
 
 	lock(&bt_lock);
 
-	___backtrace(bt_buf, &ents, &token, &r1_caller);
-	___print_backtrace(mfspr(SPR_PIR), bt_buf, ents, token, r1_caller,
-			NULL, NULL, true);
+	___backtrace(bt_buf, STACK_BUF_ENTRIES, &metadata);
+	___print_backtrace(bt_buf, &metadata, NULL, NULL, true);
 
 	unlock(&bt_lock);
 }
diff --git a/include/stack.h b/include/stack.h
index ae910a3211a0..d8baf8dc7773 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -107,36 +107,52 @@ struct stack_frame {
 	uint64_t	dar;
 } __attribute__((aligned(16)));
 
-/* Backtrace */
+/* Backtrace entry */
 struct bt_entry {
 	unsigned long	sp;
 	unsigned long	pc;
 };
 
+/* Backtrace metadata */
+struct bt_metadata {
+	unsigned int	ents;
+	unsigned long	token;
+	unsigned long	r1_caller;
+	unsigned long	pir;
+};
+
 /* Boot stack top */
 extern void *boot_stack_top;
 
 /* Create a backtrace */
-void ___backtrace(struct bt_entry *entries, unsigned int *count,
-				unsigned long *token, unsigned long *r1_caller);
+void ___backtrace(struct bt_entry *entries, unsigned int max_ents,
+		  struct bt_metadata *metadata);
+
 static inline void __backtrace(struct bt_entry *entries, unsigned int *count)
 {
-	unsigned long token, r1_caller;
+	struct bt_metadata metadata;
+
+	___backtrace(entries, *count, &metadata);
 
-	___backtrace(entries, count, &token, &r1_caller);
+	*count = metadata.ents;
 }
 
 /* Convert a backtrace to ASCII */
-extern void ___print_backtrace(unsigned int pir, struct bt_entry *entries,
-			      unsigned int count, unsigned long token,
-			      unsigned long r1_caller, char *out_buf,
-			      unsigned int *len, bool symbols);
+extern void ___print_backtrace(struct bt_entry *entries,
+			       struct bt_metadata *metadata, char *out_buf,
+			       unsigned int *len, bool symbols);
 
 static inline void __print_backtrace(unsigned int pir, struct bt_entry *entries,
-			      unsigned int count, char *out_buf,
-			      unsigned int *len, bool symbols)
+				     unsigned int count, char *out_buf,
+				     unsigned int *len, bool symbols)
 {
-	___print_backtrace(pir, entries, count, OPAL_LAST + 1, 0, out_buf, len, symbols);
+	struct bt_metadata metadata = {
+		.ents = count,
+		.token = OPAL_LAST + 1,
+		.r1_caller = 0,
+		.pir = pir
+	};
+	___print_backtrace(entries, &metadata, out_buf, len, symbols);
 }
 
 /* For use by debug code, create and print backtrace, uses a static buffer */
-- 
2.11.0



More information about the Skiboot mailing list