|
@@ -964,8 +964,6 @@ static void push_to_pool(struct work_struct *work)
|
|
static size_t account(struct entropy_store *r, size_t nbytes, int min,
|
|
static size_t account(struct entropy_store *r, size_t nbytes, int min,
|
|
int reserved)
|
|
int reserved)
|
|
{
|
|
{
|
|
- unsigned long flags;
|
|
|
|
- int wakeup_write = 0;
|
|
|
|
int have_bytes;
|
|
int have_bytes;
|
|
int entropy_count, orig;
|
|
int entropy_count, orig;
|
|
size_t ibytes;
|
|
size_t ibytes;
|
|
@@ -977,24 +975,19 @@ retry:
|
|
entropy_count = orig = ACCESS_ONCE(r->entropy_count);
|
|
entropy_count = orig = ACCESS_ONCE(r->entropy_count);
|
|
have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
|
|
have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
|
|
ibytes = nbytes;
|
|
ibytes = nbytes;
|
|
- if (have_bytes < min + reserved) {
|
|
|
|
|
|
+ /* If limited, never pull more than available */
|
|
|
|
+ if (r->limit)
|
|
|
|
+ ibytes = min_t(size_t, ibytes, have_bytes - reserved);
|
|
|
|
+ if (ibytes < min)
|
|
ibytes = 0;
|
|
ibytes = 0;
|
|
- } else {
|
|
|
|
- /* If limited, never pull more than available */
|
|
|
|
- if (r->limit)
|
|
|
|
- ibytes = min_t(size_t, ibytes, have_bytes - reserved);
|
|
|
|
- entropy_count = max_t(int, 0,
|
|
|
|
- entropy_count - (ibytes << (ENTROPY_SHIFT + 3)));
|
|
|
|
- if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
|
|
|
|
- goto retry;
|
|
|
|
-
|
|
|
|
- if ((r->entropy_count >> ENTROPY_SHIFT)
|
|
|
|
- < random_write_wakeup_thresh)
|
|
|
|
- wakeup_write = 1;
|
|
|
|
- }
|
|
|
|
|
|
+ entropy_count = max_t(int, 0,
|
|
|
|
+ entropy_count - (ibytes << (ENTROPY_SHIFT + 3)));
|
|
|
|
+ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
|
|
|
|
+ goto retry;
|
|
|
|
|
|
trace_debit_entropy(r->name, 8 * ibytes);
|
|
trace_debit_entropy(r->name, 8 * ibytes);
|
|
- if (wakeup_write) {
|
|
|
|
|
|
+ if (ibytes &&
|
|
|
|
+ (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_thresh) {
|
|
wake_up_interruptible(&random_write_wait);
|
|
wake_up_interruptible(&random_write_wait);
|
|
kill_fasync(&fasync, SIGIO, POLL_OUT);
|
|
kill_fasync(&fasync, SIGIO, POLL_OUT);
|
|
}
|
|
}
|