diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2013-09-10 23:16:17 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-10-10 14:32:13 -0400 |
commit | 9ed17b70b409dc48c134a80b5a6df582ba759de2 (patch) | |
tree | 5e1efaa318847e95e46c46d5ea800c50e253c865 /drivers/char | |
parent | 85a1f77716cf546d9b9c42e2848b5712f51ba1ee (diff) |
random: statically compute poolbitshift, poolbytes, poolbits
Use a macro to statically compute poolbitshift (will be used in a
subsequent patch), poolbytes, and poolbits. On virtually all
architectures the cost of a memory load with an offset is the same as
the one of a memory load.
It is still possible for this to generate worse code since the C
compiler doesn't know the fixed relationship between these fields, but
that is somewhat unlikely.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/random.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 54d020815b4e..20651a2fd8a7 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -309,46 +309,45 @@ static DEFINE_PER_CPU(int, trickle_count); | |||
309 | * scaled squared error sum) except for the last tap, which is 1 to | 309 | * scaled squared error sum) except for the last tap, which is 1 to |
310 | * get the twisting happening as fast as possible. | 310 | * get the twisting happening as fast as possible. |
311 | */ | 311 | */ |
312 | |||
312 | static struct poolinfo { | 313 | static struct poolinfo { |
313 | int poolwords; | 314 | int poolbitshift, poolwords, poolbytes, poolbits; |
315 | #define S(x) ilog2(x)+5, (x), (x)*4, (x)*32 | ||
314 | int tap1, tap2, tap3, tap4, tap5; | 316 | int tap1, tap2, tap3, tap4, tap5; |
315 | } poolinfo_table[] = { | 317 | } poolinfo_table[] = { |
316 | /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ | 318 | /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ |
317 | { 128, 103, 76, 51, 25, 1 }, | 319 | { S(128), 103, 76, 51, 25, 1 }, |
318 | /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ | 320 | /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ |
319 | { 32, 26, 20, 14, 7, 1 }, | 321 | { S(32), 26, 20, 14, 7, 1 }, |
320 | #if 0 | 322 | #if 0 |
321 | /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ | 323 | /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ |
322 | { 2048, 1638, 1231, 819, 411, 1 }, | 324 | { S(2048), 1638, 1231, 819, 411, 1 }, |
323 | 325 | ||
324 | /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */ | 326 | /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */ |
325 | { 1024, 817, 615, 412, 204, 1 }, | 327 | { S(1024), 817, 615, 412, 204, 1 }, |
326 | 328 | ||
327 | /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */ | 329 | /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */ |
328 | { 1024, 819, 616, 410, 207, 2 }, | 330 | { S(1024), 819, 616, 410, 207, 2 }, |
329 | 331 | ||
330 | /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */ | 332 | /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */ |
331 | { 512, 411, 308, 208, 104, 1 }, | 333 | { S(512), 411, 308, 208, 104, 1 }, |
332 | 334 | ||
333 | /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */ | 335 | /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */ |
334 | { 512, 409, 307, 206, 102, 2 }, | 336 | { S(512), 409, 307, 206, 102, 2 }, |
335 | /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */ | 337 | /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */ |
336 | { 512, 409, 309, 205, 103, 2 }, | 338 | { S(512), 409, 309, 205, 103, 2 }, |
337 | 339 | ||
338 | /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */ | 340 | /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */ |
339 | { 256, 205, 155, 101, 52, 1 }, | 341 | { S(256), 205, 155, 101, 52, 1 }, |
340 | 342 | ||
341 | /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */ | 343 | /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */ |
342 | { 128, 103, 78, 51, 27, 2 }, | 344 | { S(128), 103, 78, 51, 27, 2 }, |
343 | 345 | ||
344 | /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */ | 346 | /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */ |
345 | { 64, 52, 39, 26, 14, 1 }, | 347 | { S(64), 52, 39, 26, 14, 1 }, |
346 | #endif | 348 | #endif |
347 | }; | 349 | }; |
348 | 350 | ||
349 | #define POOLBITS poolwords*32 | ||
350 | #define POOLBYTES poolwords*4 | ||
351 | |||
352 | /* | 351 | /* |
353 | * For the purposes of better mixing, we use the CRC-32 polynomial as | 352 | * For the purposes of better mixing, we use the CRC-32 polynomial as |
354 | * well to make a twisted Generalized Feedback Shift Reigster | 353 | * well to make a twisted Generalized Feedback Shift Reigster |
@@ -599,8 +598,8 @@ retry: | |||
599 | if (entropy_count < 0) { | 598 | if (entropy_count < 0) { |
600 | DEBUG_ENT("negative entropy/overflow\n"); | 599 | DEBUG_ENT("negative entropy/overflow\n"); |
601 | entropy_count = 0; | 600 | entropy_count = 0; |
602 | } else if (entropy_count > r->poolinfo->POOLBITS) | 601 | } else if (entropy_count > r->poolinfo->poolbits) |
603 | entropy_count = r->poolinfo->POOLBITS; | 602 | entropy_count = r->poolinfo->poolbits; |
604 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) | 603 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
605 | goto retry; | 604 | goto retry; |
606 | 605 | ||
@@ -815,7 +814,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
815 | __u32 tmp[OUTPUT_POOL_WORDS]; | 814 | __u32 tmp[OUTPUT_POOL_WORDS]; |
816 | 815 | ||
817 | if (r->pull && r->entropy_count < nbytes * 8 && | 816 | if (r->pull && r->entropy_count < nbytes * 8 && |
818 | r->entropy_count < r->poolinfo->POOLBITS) { | 817 | r->entropy_count < r->poolinfo->poolbits) { |
819 | /* If we're limited, always leave two wakeup worth's BITS */ | 818 | /* If we're limited, always leave two wakeup worth's BITS */ |
820 | int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; | 819 | int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; |
821 | int bytes = nbytes; | 820 | int bytes = nbytes; |
@@ -857,7 +856,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
857 | /* Hold lock while accounting */ | 856 | /* Hold lock while accounting */ |
858 | spin_lock_irqsave(&r->lock, flags); | 857 | spin_lock_irqsave(&r->lock, flags); |
859 | 858 | ||
860 | BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); | 859 | BUG_ON(r->entropy_count > r->poolinfo->poolbits); |
861 | DEBUG_ENT("trying to extract %zu bits from %s\n", | 860 | DEBUG_ENT("trying to extract %zu bits from %s\n", |
862 | nbytes * 8, r->name); | 861 | nbytes * 8, r->name); |
863 | 862 | ||
@@ -1112,7 +1111,7 @@ static void init_std_data(struct entropy_store *r) | |||
1112 | r->entropy_total = 0; | 1111 | r->entropy_total = 0; |
1113 | r->last_data_init = false; | 1112 | r->last_data_init = false; |
1114 | mix_pool_bytes(r, &now, sizeof(now), NULL); | 1113 | mix_pool_bytes(r, &now, sizeof(now), NULL); |
1115 | for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { | 1114 | for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { |
1116 | if (!arch_get_random_long(&rv)) | 1115 | if (!arch_get_random_long(&rv)) |
1117 | break; | 1116 | break; |
1118 | mix_pool_bytes(r, &rv, sizeof(rv), NULL); | 1117 | mix_pool_bytes(r, &rv, sizeof(rv), NULL); |