powerpc: Add a (CPU/runtime features) flags set to pcpu struct

Summary:
The point of this addition is to cache CPU behavior 'features', to avoid
having to recompute based on CPU, etc.

The first such use case is to avoid the unnecessary manipulation of the
SLBs (Segment Lookaside Buffers) when using the Radix pmap on POWER9.
Since we already get the PCPU pointer wherever we swap the SLB entries,
we can use a cached flag to check if it's necessary to perform the
operation anyway, and skip it when not.

Reviewed by:	bdragon
Differential Revision:	https://reviews.freebsd.org/D24908
This commit is contained in:
jhibbits 2020-06-06 02:40:52 +00:00
parent cb74bd6a39
commit bfb1e3274b
6 changed files with 16 additions and 0 deletions

View File

@ -2327,6 +2327,7 @@ mmu_radix_bootstrap(vm_offset_t start, vm_offset_t end)
printf("%s done\n", __func__);
pmap_bootstrapped = 1;
dmaplimit = roundup2(powerpc_ptob(Maxmem), L2_PAGE_SIZE);
PCPU_SET(flags, PCPU_GET(flags) | PC_FLAG_NOSRS);
}
static void

View File

@ -87,6 +87,9 @@ restore_usersrs:
*/
restore_kernsrs:
GET_CPUINFO(%r28)
lwz %r29, PC_FLAGS(%r28)
mtcr %r29
btlr 0
addi %r28,%r28,PC_KERNSLB
ld %r29,16(%r28) /* One past USER_SLB_SLOT */
cmpdi %r29,0
@ -270,9 +273,13 @@ restore_kernsrs:
std %r29,(savearea+CPUSAVE_R29)(%r3); \
std %r30,(savearea+CPUSAVE_R30)(%r3); \
std %r31,(savearea+CPUSAVE_R31)(%r3); \
lwz %r28,PC_FLAGS(%r3); \
mtcr %r28; \
bt 0, 0f; /* Check to skip restoring SRs. */ \
mflr %r27; /* preserve LR */ \
bl restore_usersrs; /* uses r28-r31 */ \
mtlr %r27; \
0: \
ld %r31,(savearea+CPUSAVE_R31)(%r3); \
ld %r30,(savearea+CPUSAVE_R30)(%r3); \
ld %r29,(savearea+CPUSAVE_R29)(%r3); \

View File

@ -50,6 +50,7 @@ struct pvo_entry;
int pc_bsp; \
volatile int pc_awake; \
uint32_t pc_ipimask; \
uint32_t pc_flags; /* cpu feature flags */ \
register_t pc_tempsave[CPUSAVE_LEN]; \
register_t pc_disisave[CPUSAVE_LEN]; \
register_t pc_dbsave[CPUSAVE_LEN]; \
@ -77,6 +78,9 @@ struct pvo_entry;
#define PCPU_MD_AIM_FIELDS PCPU_MD_AIM32_FIELDS
#endif
/* CPU feature flags, can be used for cached flow control. */
#define PC_FLAG_NOSRS 0x80000000
#define BOOKE_CRITSAVE_LEN (CPUSAVE_LEN + 2)
#define BOOKE_TLB_MAXNEST 4
#define BOOKE_TLB_SAVELEN 16

View File

@ -91,4 +91,5 @@ db_show_mdpcpu(struct pcpu *pc)
db_printf("PPC: hwref = %#zx\n", pc->pc_hwref);
db_printf("PPC: ipimask = %#x\n", pc->pc_ipimask);
db_printf("PPC: flags = %#x\n", pc->pc_flags);
}

View File

@ -64,6 +64,7 @@ ASSYM(PC_TEMPSAVE, offsetof(struct pcpu, pc_tempsave));
ASSYM(PC_DISISAVE, offsetof(struct pcpu, pc_disisave));
ASSYM(PC_DBSAVE, offsetof(struct pcpu, pc_dbsave));
ASSYM(PC_RESTORE, offsetof(struct pcpu, pc_restore));
ASSYM(PC_FLAGS, offsetof(struct pcpu, pc_flags));
#if defined(BOOKE)
ASSYM(PC_BOOKE_CRITSAVE, offsetof(struct pcpu, pc_booke.critsave));
@ -106,6 +107,7 @@ ASSYM(TLBSAVE_BOOKE_R31, TLBSAVE_BOOKE_R31*sizeof(register_t));
ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock));
ASSYM(PC_FLAG_NOSRS, PC_FLAG_NOSRS);
#if defined(AIM)
ASSYM(USER_ADDR, USER_ADDR);
#ifdef __powerpc64__

View File

@ -246,6 +246,7 @@ cpu_mp_unleash(void *dummy)
printf("Waking up CPU %d (dev=%x)\n",
pc->pc_cpuid, (int)pc->pc_hwref);
pc->pc_flags = PCPU_GET(flags); /* Copy cached CPU flags */
ret = platform_smp_start_cpu(pc);
if (ret == 0) {
timeout = 2000; /* wait 2sec for the AP */