aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Munsie <imunsie@au1.ibm.com>2014-10-27 23:25:27 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2014-10-28 04:52:07 -0400
commit5100a9d6444bf205de49190431b0d08de43b86e9 (patch)
treefb3d3cf60fc6076c9fd6c5e03c8ee340caa5f5e9
parentbf19edd290d5d2d53bba53f7f4cb2f7492997009 (diff)
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>
-rw-r--r--drivers/misc/cxl/fault.c30
-rw-r--r--drivers/misc/cxl/native.c4
2 files changed, 10 insertions, 24 deletions
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 69506ebd4d07..d0e97fd3d4c5 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -22,29 +22,19 @@
22#include "cxl.h" 22#include "cxl.h"
23 23
24static struct cxl_sste* find_free_sste(struct cxl_sste *primary_group, 24static struct cxl_sste* find_free_sste(struct cxl_sste *primary_group,
25 bool sec_hash,
26 struct cxl_sste *secondary_group,
27 unsigned int *lru) 25 unsigned int *lru)
28{ 26{
29 unsigned int i, entry; 27 unsigned int entry;
30 struct cxl_sste *sste, *group = primary_group; 28 struct cxl_sste *sste, *group = primary_group;
31 29
32 for (i = 0; i < 2; i++) { 30 for (entry = 0; entry < 8; entry++) {
33 for (entry = 0; entry < 8; entry++) { 31 sste = group + entry;
34 sste = group + entry; 32 if (!(be64_to_cpu(sste->esid_data) & SLB_ESID_V))
35 if (!(be64_to_cpu(sste->esid_data) & SLB_ESID_V)) 33 return sste;
36 return sste;
37 }
38 if (!sec_hash)
39 break;
40 group = secondary_group;
41 } 34 }
42 /* Nothing free, select an entry to cast out */ 35 /* Nothing free, select an entry to cast out */
43 if (sec_hash && (*lru & 0x8)) 36 sste = primary_group + *lru;
44 sste = secondary_group + (*lru & 0x7); 37 *lru = (*lru + 1) & 0x7;
45 else
46 sste = primary_group + (*lru & 0x7);
47 *lru = (*lru + 1) & 0xf;
48 38
49 return sste; 39 return sste;
50} 40}
@@ -53,22 +43,18 @@ static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb)
53{ 43{
54 /* mask is the group index, we search primary and secondary here. */ 44 /* mask is the group index, we search primary and secondary here. */
55 unsigned int mask = (ctx->sst_size >> 7)-1; /* SSTP0[SegTableSize] */ 45 unsigned int mask = (ctx->sst_size >> 7)-1; /* SSTP0[SegTableSize] */
56 bool sec_hash = 1;
57 struct cxl_sste *sste; 46 struct cxl_sste *sste;
58 unsigned int hash; 47 unsigned int hash;
59 unsigned long flags; 48 unsigned long flags;
60 49
61 50
62 sec_hash = !!(cxl_p1n_read(ctx->afu, CXL_PSL_SR_An) & CXL_PSL_SR_An_SC);
63
64 if (slb->vsid & SLB_VSID_B_1T) 51 if (slb->vsid & SLB_VSID_B_1T)
65 hash = (slb->esid >> SID_SHIFT_1T) & mask; 52 hash = (slb->esid >> SID_SHIFT_1T) & mask;
66 else /* 256M */ 53 else /* 256M */
67 hash = (slb->esid >> SID_SHIFT) & mask; 54 hash = (slb->esid >> SID_SHIFT) & mask;
68 55
69 spin_lock_irqsave(&ctx->sste_lock, flags); 56 spin_lock_irqsave(&ctx->sste_lock, flags);
70 sste = find_free_sste(ctx->sstp + (hash << 3), sec_hash, 57 sste = find_free_sste(ctx->sstp + (hash << 3), &ctx->sst_lru);
71 ctx->sstp + ((~hash & mask) << 3), &ctx->sst_lru);
72 58
73 pr_devel("CXL Populating SST[%li]: %#llx %#llx\n", 59 pr_devel("CXL Populating SST[%li]: %#llx %#llx\n",
74 sste - ctx->sstp, slb->vsid, slb->esid); 60 sste - ctx->sstp, slb->vsid, slb->esid);
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 623286a77114..d47532e8f4f1 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -417,7 +417,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
417 ctx->elem->haurp = 0; /* disable */ 417 ctx->elem->haurp = 0; /* disable */
418 ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1)); 418 ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1));
419 419
420 sr = CXL_PSL_SR_An_SC; 420 sr = 0;
421 if (ctx->master) 421 if (ctx->master)
422 sr |= CXL_PSL_SR_An_MP; 422 sr |= CXL_PSL_SR_An_MP;
423 if (mfspr(SPRN_LPCR) & LPCR_TC) 423 if (mfspr(SPRN_LPCR) & LPCR_TC)
@@ -508,7 +508,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
508 u64 sr; 508 u64 sr;
509 int rc; 509 int rc;
510 510
511 sr = CXL_PSL_SR_An_SC; 511 sr = 0;
512 set_endian(sr); 512 set_endian(sr);
513 if (ctx->master) 513 if (ctx->master)
514 sr |= CXL_PSL_SR_An_MP; 514 sr |= CXL_PSL_SR_An_MP;