erofs: simplify try_to_claim_pcluster()

simplify try_to_claim_pcluster() by directly using cmpxchg() here
(the retry loop caused more overhead.) Also, move the chain loop
detection in and rename it to z_erofs_try_to_claim_pcluster().

Link: https://lore.kernel.org/r/20201208095834.3133565-3-hsiangkao@redhat.com
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
This commit is contained in:
Gao Xiang 2020-12-08 17:58:34 +08:00
parent bf225074ff
commit 473e15b0c0
1 changed files with 25 additions and 28 deletions

View File

@ -292,34 +292,33 @@ static int z_erofs_attach_page(struct z_erofs_collector *clt,
return ret ? 0 : -EAGAIN;
}
static enum z_erofs_collectmode
try_to_claim_pcluster(struct z_erofs_pcluster *pcl,
z_erofs_next_pcluster_t *owned_head)
static void z_erofs_try_to_claim_pcluster(struct z_erofs_collector *clt)
{
/* let's claim these following types of pclusters */
retry:
if (pcl->next == Z_EROFS_PCLUSTER_NIL) {
/* type 1, nil pcluster */
if (cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_NIL,
*owned_head) != Z_EROFS_PCLUSTER_NIL)
goto retry;
struct z_erofs_pcluster *pcl = clt->pcl;
z_erofs_next_pcluster_t *owned_head = &clt->owned_head;
/* type 1, nil pcluster (this pcluster doesn't belong to any chain.) */
if (cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_NIL,
*owned_head) == Z_EROFS_PCLUSTER_NIL) {
*owned_head = &pcl->next;
/* lucky, I am the followee :) */
return COLLECT_PRIMARY_FOLLOWED;
} else if (pcl->next == Z_EROFS_PCLUSTER_TAIL) {
/*
* type 2, link to the end of a existing open chain,
* be careful that its submission itself is governed
* by the original owned chain.
*/
if (cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_TAIL,
*owned_head) != Z_EROFS_PCLUSTER_TAIL)
goto retry;
*owned_head = Z_EROFS_PCLUSTER_TAIL;
return COLLECT_PRIMARY_HOOKED;
/* so we can attach this pcluster to our submission chain. */
clt->mode = COLLECT_PRIMARY_FOLLOWED;
return;
}
return COLLECT_PRIMARY; /* :( better luck next time */
/*
* type 2, link to the end of an existing open chain, be careful
* that its submission is controlled by the original attached chain.
*/
if (cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_TAIL,
*owned_head) == Z_EROFS_PCLUSTER_TAIL) {
*owned_head = Z_EROFS_PCLUSTER_TAIL;
clt->mode = COLLECT_PRIMARY_HOOKED;
clt->tailpcl = NULL;
return;
}
/* type 3, it belongs to a chain, but it isn't the end of the chain */
clt->mode = COLLECT_PRIMARY;
}
static int z_erofs_lookup_collection(struct z_erofs_collector *clt,
@ -364,10 +363,8 @@ static int z_erofs_lookup_collection(struct z_erofs_collector *clt,
/* used to check tail merging loop due to corrupted images */
if (clt->owned_head == Z_EROFS_PCLUSTER_TAIL)
clt->tailpcl = pcl;
clt->mode = try_to_claim_pcluster(pcl, &clt->owned_head);
/* clean tailpcl if the current owned_head is Z_EROFS_PCLUSTER_TAIL */
if (clt->owned_head == Z_EROFS_PCLUSTER_TAIL)
clt->tailpcl = NULL;
z_erofs_try_to_claim_pcluster(clt);
clt->cl = cl;
return 0;
}