Skip to content

Commit

Permalink
crypto: api - Remove instance larval fulfilment
Browse files Browse the repository at this point in the history
In order to allow testing to complete asynchronously after the
registration process, instance larvals need to complete prior
to having a test result.  Support this by redoing the lookup for
instance larvals after completion.   This should locate the pending
test larval and then repeat the wait on that (if it is still pending).

As the lookup is now repeated there is no longer any need to compute
the fulfilment status and all that code can be removed.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
herbertx committed Aug 24, 2024
1 parent 7ccb750 commit 96ad595
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 49 deletions.
48 changes: 3 additions & 45 deletions crypto/algapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
EXPORT_SYMBOL_GPL(crypto_remove_spawns);

static void crypto_alg_finish_registration(struct crypto_alg *alg,
bool fulfill_requests,
struct list_head *algs_to_put)
{
struct crypto_alg *q;
Expand All @@ -247,30 +246,8 @@ static void crypto_alg_finish_registration(struct crypto_alg *alg,
if (crypto_is_moribund(q))
continue;

if (crypto_is_larval(q)) {
struct crypto_larval *larval = (void *)q;

/*
* Check to see if either our generic name or
* specific name can satisfy the name requested
* by the larval entry q.
*/
if (strcmp(alg->cra_name, q->cra_name) &&
strcmp(alg->cra_driver_name, q->cra_name))
continue;

if (larval->adult)
continue;
if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
continue;

if (fulfill_requests && crypto_mod_get(alg))
larval->adult = alg;
else
larval->adult = ERR_PTR(-EAGAIN);

if (crypto_is_larval(q))
continue;
}

if (strcmp(alg->cra_name, q->cra_name))
continue;
Expand Down Expand Up @@ -359,7 +336,7 @@ __crypto_register_alg(struct crypto_alg *alg, struct list_head *algs_to_put)
list_add(&larval->alg.cra_list, &crypto_alg_list);
} else {
alg->cra_flags |= CRYPTO_ALG_TESTED;
crypto_alg_finish_registration(alg, true, algs_to_put);
crypto_alg_finish_registration(alg, algs_to_put);
}

out:
Expand All @@ -376,7 +353,6 @@ void crypto_alg_tested(const char *name, int err)
struct crypto_alg *alg;
struct crypto_alg *q;
LIST_HEAD(list);
bool best;

down_write(&crypto_alg_sem);
list_for_each_entry(q, &crypto_alg_list, cra_list) {
Expand Down Expand Up @@ -408,25 +384,7 @@ void crypto_alg_tested(const char *name, int err)

alg->cra_flags |= CRYPTO_ALG_TESTED;

/*
* If a higher-priority implementation of the same algorithm is
* currently being tested, then don't fulfill request larvals.
*/
best = true;
list_for_each_entry(q, &crypto_alg_list, cra_list) {
if (crypto_is_moribund(q) || !crypto_is_larval(q))
continue;

if (strcmp(alg->cra_name, q->cra_name))
continue;

if (q->cra_priority > alg->cra_priority) {
best = false;
break;
}
}

crypto_alg_finish_registration(alg, best, &list);
crypto_alg_finish_registration(alg, &list);

complete:
complete_all(&test->completion);
Expand Down
1 change: 1 addition & 0 deletions crypto/algboss.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ static int cryptomgr_probe(void *data)
crypto_tmpl_put(tmpl);

out:
param->larval->alg.cra_flags |= CRYPTO_ALG_DEAD;
complete_all(&param->larval->completion);
crypto_alg_put(&param->larval->alg);
kfree(param);
Expand Down
23 changes: 19 additions & 4 deletions crypto/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ DEFINE_STATIC_KEY_FALSE(__crypto_boot_test_finished);
#endif

static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
u32 mask);

struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
{
Expand Down Expand Up @@ -201,9 +203,12 @@ static void crypto_start_test(struct crypto_larval *larval)

static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
{
struct crypto_larval *larval = (void *)alg;
struct crypto_larval *larval;
long time_left;

again:
larval = container_of(alg, struct crypto_larval, alg);

if (!crypto_boot_test_finished())
crypto_start_test(larval);

Expand All @@ -215,9 +220,16 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
alg = ERR_PTR(-EINTR);
else if (!time_left)
alg = ERR_PTR(-ETIMEDOUT);
else if (!alg)
alg = ERR_PTR(-ENOENT);
else if (IS_ERR(alg))
else if (!alg) {
u32 type;
u32 mask;

alg = &larval->alg;
type = alg->cra_flags & ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
mask = larval->mask;
alg = crypto_alg_lookup(alg->cra_name, type, mask) ?:
ERR_PTR(-ENOENT);
} else if (IS_ERR(alg))
;
else if (crypto_is_test_larval(larval) &&
!(alg->cra_flags & CRYPTO_ALG_TESTED))
Expand All @@ -228,6 +240,9 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
alg = ERR_PTR(-EAGAIN);
crypto_mod_put(&larval->alg);

if (!IS_ERR(alg) && crypto_is_larval(alg))
goto again;

return alg;
}

Expand Down

0 comments on commit 96ad595

Please sign in to comment.