diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2012-09-09 22:52:56 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-09-17 02:31:53 -0400 |
commit | f033d659c3b931d8b2a16625155e20304e173c9f (patch) | |
tree | 1e7cdacc0a981a77209ea04e4449b9beb52f097d /arch/powerpc | |
parent | 048ee0993ec8360abb0b51bdf8f8721e9ed62ec4 (diff) |
powerpc/mm: Update VSID allocation documentation
This update the proto-VSID and VSID scramble related information
to be more generic by using names instead of current values.
Reviewed-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/mmu-hash64.h | 40 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_context_hash64.c | 8 |
2 files changed, 22 insertions, 26 deletions
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index 23730ee65aa0..3e887467a6d1 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h | |||
@@ -324,51 +324,45 @@ extern void slb_set_size(u16 size); | |||
324 | #endif /* __ASSEMBLY__ */ | 324 | #endif /* __ASSEMBLY__ */ |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * VSID allocation | 327 | * VSID allocation (256MB segment) |
328 | * | 328 | * |
329 | * We first generate a 36-bit "proto-VSID". For kernel addresses this | 329 | * We first generate a 38-bit "proto-VSID". For kernel addresses this |
330 | * is equal to the ESID, for user addresses it is: | 330 | * is equal to the ESID | 1 << 37, for user addresses it is: |
331 | * (context << 15) | (esid & 0x7fff) | 331 | * (context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1) |
332 | * | 332 | * |
333 | * The two forms are distinguishable because the top bit is 0 for user | 333 | * This splits the proto-VSID into the below range |
334 | * addresses, whereas the top two bits are 1 for kernel addresses. | 334 | * 0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range |
335 | * Proto-VSIDs with the top two bits equal to 0b10 are reserved for | 335 | * 2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range |
336 | * now. | 336 | * |
337 | * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1 | ||
338 | * That is, we assign half of the space to user processes and half | ||
339 | * to the kernel. | ||
337 | * | 340 | * |
338 | * The proto-VSIDs are then scrambled into real VSIDs with the | 341 | * The proto-VSIDs are then scrambled into real VSIDs with the |
339 | * multiplicative hash: | 342 | * multiplicative hash: |
340 | * | 343 | * |
341 | * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS | 344 | * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS |
342 | * where VSID_MULTIPLIER = 268435399 = 0xFFFFFC7 | ||
343 | * VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF | ||
344 | * | 345 | * |
345 | * This scramble is only well defined for proto-VSIDs below | 346 | * VSID_MULTIPLIER is prime, so in particular it is |
346 | * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are | ||
347 | * reserved. VSID_MULTIPLIER is prime, so in particular it is | ||
348 | * co-prime to VSID_MODULUS, making this a 1:1 scrambling function. | 347 | * co-prime to VSID_MODULUS, making this a 1:1 scrambling function. |
349 | * Because the modulus is 2^n-1 we can compute it efficiently without | 348 | * Because the modulus is 2^n-1 we can compute it efficiently without |
350 | * a divide or extra multiply (see below). | 349 | * a divide or extra multiply (see below). |
351 | * | 350 | * |
352 | * This scheme has several advantages over older methods: | 351 | * This scheme has several advantages over older methods: |
353 | * | 352 | * |
354 | * - We have VSIDs allocated for every kernel address | 353 | * - We have VSIDs allocated for every kernel address |
355 | * (i.e. everything above 0xC000000000000000), except the very top | 354 | * (i.e. everything above 0xC000000000000000), except the very top |
356 | * segment, which simplifies several things. | 355 | * segment, which simplifies several things. |
357 | * | 356 | * |
358 | * - We allow for 16 significant bits of ESID and 19 bits of | 357 | * - We allow for USER_ESID_BITS significant bits of ESID and |
359 | * context for user addresses. i.e. 16T (44 bits) of address space for | 358 | * CONTEXT_BITS bits of context for user addresses. |
360 | * up to half a million contexts. | 359 | * i.e. 64T (46 bits) of address space for up to half a million contexts. |
361 | * | 360 | * |
362 | * - The scramble function gives robust scattering in the hash | 361 | * - The scramble function gives robust scattering in the hash |
363 | * table (at least based on some initial results). The previous | 362 | * table (at least based on some initial results). The previous |
364 | * method was more susceptible to pathological cases giving excessive | 363 | * method was more susceptible to pathological cases giving excessive |
365 | * hash collisions. | 364 | * hash collisions. |
366 | */ | 365 | */ |
367 | /* | ||
368 | * WARNING - If you change these you must make sure the asm | ||
369 | * implementations in slb_allocate (slb_low.S), do_stab_bolted | ||
370 | * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly. | ||
371 | */ | ||
372 | 366 | ||
373 | /* | 367 | /* |
374 | * This should be computed such that protovosid * vsid_mulitplier | 368 | * This should be computed such that protovosid * vsid_mulitplier |
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c index daa076c9025c..40bc5b0ace54 100644 --- a/arch/powerpc/mm/mmu_context_hash64.c +++ b/arch/powerpc/mm/mmu_context_hash64.c | |||
@@ -30,9 +30,11 @@ static DEFINE_SPINLOCK(mmu_context_lock); | |||
30 | static DEFINE_IDA(mmu_context_ida); | 30 | static DEFINE_IDA(mmu_context_ida); |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * The proto-VSID space has 2^35 - 1 segments available for user mappings. | 33 | * 256MB segment |
34 | * Each segment contains 2^28 bytes. Each context maps 2^44 bytes, | 34 | * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments |
35 | * so we can support 2^19-1 contexts (19 == 35 + 28 - 44). | 35 | * available for user mappings. Each segment contains 2^28 bytes. Each |
36 | * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts | ||
37 | * (19 == 37 + 28 - 46). | ||
36 | */ | 38 | */ |
37 | #define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1) | 39 | #define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1) |
38 | 40 | ||