[6/6] main: Address by linux CPU number with PPC host backend

Message ID 20180703065810.14917-6-mikey@neuling.org
State New
Headers show
Series
  • [1/6] htm: Fix compiling on ARM
Related show

Commit Message

Michael Neuling July 3, 2018, 6:58 a.m.
With the PPC host backend used for HTM it's difficult to match up the
hardware numbers used pdbg with linux CPU numbers that people want to
affinitise a workload against (ie. taskset -c <cpu number>).

This adds a new "-l <cpu>" options so users can address the CPU to
target using linux CPU numbers. This is only available when using the
host backend on POWER machines.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 src/main.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 2 deletions(-)

Comments

Alistair Popple July 12, 2018, 3:58 a.m. | #1
> +		/* FIXME host target is used POWER8 only currently */

This isn't really true though - we can (and do) use the host target for POWER9
as well (although not for HTM I suppose). Are the below macros different for P9?
If so I guess we might need something to detect P8 vs. P9.

> +		chip = P8_PIR2GCID(pir);
> +		core = P8_PIR2COREID(pir);
> +		thread = P8_PIR2THREADID(pir);
> +
> +		threadsel[chip][core][thread] = 1;
> +		chipsel[chip][core] = &threadsel[chip][core][thread];
> +		processorsel[chip] = &chipsel[chip][core];
> +	}
>  	return true;
>  }
>  
> 

- Alistair
Michael Neuling July 12, 2018, 6:05 a.m. | #2
On Thu, 2018-07-12 at 13:58 +1000, Alistair Popple wrote:
> > +		/* FIXME host target is used POWER8 only currently */
> 
> This isn't really true though - we can (and do) use the host target for POWER9
> as well (although not for HTM I suppose). 

Arrh, sorry, yeah I was thinking htm but this is generic so applies everywhere.

> Are the below macros different for P9?

Yeah they are.  I'll update.

> If so I guess we might need something to detect P8 vs. P9.

Yep.

Mikey
Alistair Popple July 12, 2018, 6:16 a.m. | #3
On Thursday, 12 July 2018 4:05:26 PM AEST Michael Neuling wrote:
> On Thu, 2018-07-12 at 13:58 +1000, Alistair Popple wrote:
> > > +		/* FIXME host target is used POWER8 only currently */
> > 
> > This isn't really true though - we can (and do) use the host target for POWER9
> > as well (although not for HTM I suppose). 
> 
> Arrh, sorry, yeah I was thinking htm but this is generic so applies everywhere.
> 
> > Are the below macros different for P9?
> 
> Yeah they are.  I'll update.

Thanks. I've taken the rest of the patches in this series so if you want to
resend you only need to resend this one.

- Alistair

> > If so I guess we might need something to detect P8 vs. P9.
> 
> Yep.
> 
> Mikey
>

Patch

diff --git a/src/main.c b/src/main.c
index 1efbcc635a..61f3a9f119 100644
--- a/src/main.c
+++ b/src/main.c
@@ -139,6 +139,9 @@  static void print_usage(char *pname)
 	printf("\t-p, --processor=<0-%d>|<range>|<list>\n", MAX_PROCESSORS-1);
 	printf("\t-c, --chip=<0-%d>|<range>|<list>\n", MAX_CHIPS-1);
 	printf("\t-t, --thread=<0-%d>|<range>|<list>\n", MAX_THREADS-1);
+#ifdef TARGET_PPC
+	printf("\t-l, --cpu=<0-%d>|<range>|<list>\n", MAX_PROCESSORS-1);
+#endif
 	printf("\t-a, --all\n");
 	printf("\t\tRun command on all possible processors/chips/threads (default)\n");
 	printf("\t-b, --backend=backend\n");
@@ -242,6 +245,46 @@  static bool parse_list(const char *arg, int max, int *list, int *count)
 	return true;
 }
 
+int get_pir(int linux_cpu)
+{
+	char *filename;
+	FILE *file;
+	int pir = -1;
+
+	if(asprintf(&filename, "/sys/devices/system/cpu/cpu%i/pir",
+		    linux_cpu) < 0)
+		return -1;
+
+	file = fopen(filename, "r");
+	if (!file) {
+		PR_ERROR("Invalid Linux CPU number %" PRIi32 "\n", linux_cpu);
+		goto out2;
+	}
+
+	if(fscanf(file, "%" PRIx32 "\n", &pir) != 1) {
+		PR_ERROR("fscanf() didn't match: %m\n");
+		pir = -1;
+		goto out1;
+	}
+
+out1:
+	fclose(file);
+out2:
+	free(filename);
+	return pir;
+}
+
+/* Stolen from skiboot */
+#define P8_PIR2GCID(pir) (((pir) >> 7) & 0x3f)
+#define P8_PIR2COREID(pir) (((pir) >> 3) & 0xf)
+#define P8_PIR2THREADID(pir) ((pir) & 0x7)
+
+#ifdef TARGET_PPC
+#define PPC_OPTS "l:"
+#else
+#define PPC_OPTS
+#endif
+
 static bool parse_options(int argc, char *argv[])
 {
 	int c;
@@ -249,7 +292,8 @@  static bool parse_options(int argc, char *argv[])
 	int p_list[MAX_PROCESSORS];
 	int c_list[MAX_CHIPS];
 	int t_list[MAX_THREADS];
-	int p_count = 0, c_count = 0, t_count = 0;
+	int l_list[MAX_PROCESSORS];
+	int p_count = 0, c_count = 0, t_count = 0, l_count = 0;
 	int i, j, k;
 	struct option long_opts[] = {
 		{"all",			no_argument,		NULL,	'a'},
@@ -260,6 +304,9 @@  static bool parse_options(int argc, char *argv[])
 		{"processor",		required_argument,	NULL,	'p'},
 		{"slave-address",	required_argument,	NULL,	's'},
 		{"thread",		required_argument,	NULL,	't'},
+#ifdef TARGET_PPC
+		{"cpu",			required_argument,	NULL,	'l'},
+#endif
 		{"debug",		required_argument,	NULL,	'D'},
 		{"version",		no_argument,		NULL,	'V'},
 		{NULL,			0,			NULL,     0}
@@ -269,9 +316,11 @@  static bool parse_options(int argc, char *argv[])
 	memset(p_list, 0, sizeof(p_list));
 	memset(c_list, 0, sizeof(c_list));
 	memset(t_list, 0, sizeof(t_list));
+	memset(l_list, 0, sizeof(l_list));
 
 	do {
-		c = getopt_long(argc, argv, "+ab:c:d:hp:s:t:D:V", long_opts, NULL);
+		c = getopt_long(argc, argv, "+ab:c:d:hp:s:t:D:V" PPC_OPTS,
+				long_opts, NULL);
 		if (c == -1)
 			break;
 
@@ -317,6 +366,15 @@  static bool parse_options(int argc, char *argv[])
 			}
 			break;
 
+#ifdef TARGET_PPC
+		case 'l':
+			if (!parse_list(optarg, MAX_PROCESSORS, l_list, &l_count)) {
+				fprintf(stderr, "Failed to parse '-l %s'\n", optarg);
+				opt_error = true;
+			}
+			break;
+#endif
+
 		case 'b':
 			if (strcmp(optarg, "fsi") == 0) {
 				backend = FSI;
@@ -403,6 +461,29 @@  static bool parse_options(int argc, char *argv[])
 		}
 	}
 
+	if (l_count) {
+		int pir = -1, i, chip, core, thread;
+
+		for (i = 0; i < MAX_PROCESSORS; i++) {
+			if (l_list[i] == 1) {
+				pir = get_pir(i);
+				if (pir < 0)
+					return true;
+				break;
+			}
+		}
+		if (pir < 0)
+			return true;
+
+		/* FIXME host target is used POWER8 only currently */
+		chip = P8_PIR2GCID(pir);
+		core = P8_PIR2COREID(pir);
+		thread = P8_PIR2THREADID(pir);
+
+		threadsel[chip][core][thread] = 1;
+		chipsel[chip][core] = &threadsel[chip][core][thread];
+		processorsel[chip] = &chipsel[chip][core];
+	}
 	return true;
 }