Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxl: Disable secondary hash in segment table

This patch simplifies the process of finding a free segment table entry
by disabling the secondary hash. This reduces the number of possible
entries in the segment table for a given address from 16 to 8.

Due to the large segment sizes we use it is extremely unlikely that the
secondary hash would ever have been used in practice, so this should not
have any negative impacts and may even improve performance due to the
reduced number of comparisons that software & hardware need to perform.

This patch clears the SC bit in the hardware's state register
(CXL_PSL_SR_An) to disable the secondary hash in the hardware since we
can no longer fill out entries using it.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Ian Munsie and committed by
Michael Ellerman
5100a9d6 bf19edd2

+10 -24
+8 -22
drivers/misc/cxl/fault.c
··· 22 22 #include "cxl.h" 23 23 24 24 static struct cxl_sste* find_free_sste(struct cxl_sste *primary_group, 25 - bool sec_hash, 26 - struct cxl_sste *secondary_group, 27 25 unsigned int *lru) 28 26 { 29 - unsigned int i, entry; 27 + unsigned int entry; 30 28 struct cxl_sste *sste, *group = primary_group; 31 29 32 - for (i = 0; i < 2; i++) { 33 - for (entry = 0; entry < 8; entry++) { 34 - sste = group + entry; 35 - if (!(be64_to_cpu(sste->esid_data) & SLB_ESID_V)) 36 - return sste; 37 - } 38 - if (!sec_hash) 39 - break; 40 - group = secondary_group; 30 + for (entry = 0; entry < 8; entry++) { 31 + sste = group + entry; 32 + if (!(be64_to_cpu(sste->esid_data) & SLB_ESID_V)) 33 + return sste; 41 34 } 42 35 /* Nothing free, select an entry to cast out */ 43 - if (sec_hash && (*lru & 0x8)) 44 - sste = secondary_group + (*lru & 0x7); 45 - else 46 - sste = primary_group + (*lru & 0x7); 47 - *lru = (*lru + 1) & 0xf; 36 + sste = primary_group + *lru; 37 + *lru = (*lru + 1) & 0x7; 48 38 49 39 return sste; 50 40 } ··· 43 53 { 44 54 /* mask is the group index, we search primary and secondary here. */ 45 55 unsigned int mask = (ctx->sst_size >> 7)-1; /* SSTP0[SegTableSize] */ 46 - bool sec_hash = 1; 47 56 struct cxl_sste *sste; 48 57 unsigned int hash; 49 58 unsigned long flags; 50 59 51 - 52 - sec_hash = !!(cxl_p1n_read(ctx->afu, CXL_PSL_SR_An) & CXL_PSL_SR_An_SC); 53 60 54 61 if (slb->vsid & SLB_VSID_B_1T) 55 62 hash = (slb->esid >> SID_SHIFT_1T) & mask; ··· 54 67 hash = (slb->esid >> SID_SHIFT) & mask; 55 68 56 69 spin_lock_irqsave(&ctx->sste_lock, flags); 57 - sste = find_free_sste(ctx->sstp + (hash << 3), sec_hash, 58 - ctx->sstp + ((~hash & mask) << 3), &ctx->sst_lru); 70 + sste = find_free_sste(ctx->sstp + (hash << 3), &ctx->sst_lru); 59 71 60 72 pr_devel("CXL Populating SST[%li]: %#llx %#llx\n", 61 73 sste - ctx->sstp, slb->vsid, slb->esid);
+2 -2
drivers/misc/cxl/native.c
··· 417 417 ctx->elem->haurp = 0; /* disable */ 418 418 ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1)); 419 419 420 - sr = CXL_PSL_SR_An_SC; 420 + sr = 0; 421 421 if (ctx->master) 422 422 sr |= CXL_PSL_SR_An_MP; 423 423 if (mfspr(SPRN_LPCR) & LPCR_TC) ··· 508 508 u64 sr; 509 509 int rc; 510 510 511 - sr = CXL_PSL_SR_An_SC; 511 + sr = 0; 512 512 set_endian(sr); 513 513 if (ctx->master) 514 514 sr |= CXL_PSL_SR_An_MP;