Commit c90e4539 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Herbert Xu

hwrng: core - do not bother to order list of devices by quality

There is no real reason why this list needs to be kept ordered by
the driver-provided quality value -- a value which is set only by
a handful of hw_random devices anyway.

Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 973d74e9
...@@ -31,7 +31,7 @@ static struct hwrng *current_rng; ...@@ -31,7 +31,7 @@ static struct hwrng *current_rng;
/* the current rng has been explicitly chosen by user via sysfs */ /* the current rng has been explicitly chosen by user via sysfs */
static int cur_rng_set_by_user; static int cur_rng_set_by_user;
static struct task_struct *hwrng_fill; static struct task_struct *hwrng_fill;
/* list of registered rngs, sorted decending by quality */ /* list of registered rngs */
static LIST_HEAD(rng_list); static LIST_HEAD(rng_list);
/* Protects rng_list and current_rng */ /* Protects rng_list and current_rng */
static DEFINE_MUTEX(rng_mutex); static DEFINE_MUTEX(rng_mutex);
...@@ -297,24 +297,28 @@ static struct miscdevice rng_miscdev = { ...@@ -297,24 +297,28 @@ static struct miscdevice rng_miscdev = {
static int enable_best_rng(void) static int enable_best_rng(void)
{ {
struct hwrng *rng, *new_rng = NULL;
int ret = -ENODEV; int ret = -ENODEV;
BUG_ON(!mutex_is_locked(&rng_mutex)); BUG_ON(!mutex_is_locked(&rng_mutex));
/* rng_list is sorted by quality, use the best (=first) one */ /* no rng to use? */
if (!list_empty(&rng_list)) { if (list_empty(&rng_list)) {
struct hwrng *new_rng;
new_rng = list_entry(rng_list.next, struct hwrng, list);
ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
if (!ret)
cur_rng_set_by_user = 0;
} else {
drop_current_rng(); drop_current_rng();
cur_rng_set_by_user = 0; cur_rng_set_by_user = 0;
ret = 0; return 0;
} }
/* use the rng which offers the best quality */
list_for_each_entry(rng, &rng_list, list) {
if (!new_rng || rng->quality > new_rng->quality)
new_rng = rng;
}
ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
if (!ret)
cur_rng_set_by_user = 0;
return ret; return ret;
} }
...@@ -475,7 +479,6 @@ int hwrng_register(struct hwrng *rng) ...@@ -475,7 +479,6 @@ int hwrng_register(struct hwrng *rng)
{ {
int err = -EINVAL; int err = -EINVAL;
struct hwrng *tmp; struct hwrng *tmp;
struct list_head *rng_list_ptr;
bool is_new_current = false; bool is_new_current = false;
if (!rng->name || (!rng->data_read && !rng->read)) if (!rng->name || (!rng->data_read && !rng->read))
...@@ -489,18 +492,11 @@ int hwrng_register(struct hwrng *rng) ...@@ -489,18 +492,11 @@ int hwrng_register(struct hwrng *rng)
if (strcmp(tmp->name, rng->name) == 0) if (strcmp(tmp->name, rng->name) == 0)
goto out_unlock; goto out_unlock;
} }
list_add_tail(&rng->list, &rng_list);
init_completion(&rng->cleanup_done); init_completion(&rng->cleanup_done);
complete(&rng->cleanup_done); complete(&rng->cleanup_done);
/* rng_list is sorted by decreasing quality */
list_for_each(rng_list_ptr, &rng_list) {
tmp = list_entry(rng_list_ptr, struct hwrng, list);
if (tmp->quality < rng->quality)
break;
}
list_add_tail(&rng->list, rng_list_ptr);
if (!current_rng || if (!current_rng ||
(!cur_rng_set_by_user && rng->quality > current_rng->quality)) { (!cur_rng_set_by_user && rng->quality > current_rng->quality)) {
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment