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

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
Loading
Loading
Loading
Loading
+16 −20
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ static struct hwrng *current_rng;
/* the current rng has been explicitly chosen by user via sysfs */
static int cur_rng_set_by_user;
static struct task_struct *hwrng_fill;
/* list of registered rngs, sorted decending by quality */
/* list of registered rngs */
static LIST_HEAD(rng_list);
/* Protects rng_list and current_rng */
static DEFINE_MUTEX(rng_mutex);
@@ -297,23 +297,27 @@ static struct miscdevice rng_miscdev = {

static int enable_best_rng(void)
{
	struct hwrng *rng, *new_rng = NULL;
	int ret = -ENODEV;

	BUG_ON(!mutex_is_locked(&rng_mutex));

	/* rng_list is sorted by quality, use the best (=first) one */
	if (!list_empty(&rng_list)) {
		struct hwrng *new_rng;
	/* no rng to use? */
	if (list_empty(&rng_list)) {
		drop_current_rng();
		cur_rng_set_by_user = 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;
	}

		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();
		cur_rng_set_by_user = 0;
		ret = 0;
	}

	return ret;
}
@@ -475,7 +479,6 @@ int hwrng_register(struct hwrng *rng)
{
	int err = -EINVAL;
	struct hwrng *tmp;
	struct list_head *rng_list_ptr;
	bool is_new_current = false;

	if (!rng->name || (!rng->data_read && !rng->read))
@@ -489,18 +492,11 @@ int hwrng_register(struct hwrng *rng)
		if (strcmp(tmp->name, rng->name) == 0)
			goto out_unlock;
	}
	list_add_tail(&rng->list, &rng_list);

	init_completion(&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 ||
	    (!cur_rng_set_by_user && rng->quality > current_rng->quality)) {
		/*