@@ -2698,9 +2698,12 @@ static struct slab_sheaf *barn_get_empty_sheaf(struct node_barn *barn)
struct slab_sheaf *empty = NULL;
unsigned long flags;
+ if (!data_race(barn->nr_empty))
+ return NULL;
+
spin_lock_irqsave(&barn->lock, flags);
- if (barn->nr_empty) {
+ if (likely(barn->nr_empty)) {
empty = list_first_entry(&barn->sheaves_empty,
struct slab_sheaf, barn_list);
list_del(&empty->barn_list);
@@ -2716,38 +2719,36 @@ static int barn_put_empty_sheaf(struct node_barn *barn,
struct slab_sheaf *sheaf, bool ignore_limit)
{
unsigned long flags;
- int ret = 0;
+
+ /* we don't repeat the check under barn->lock as it's not critical */
+ if (!ignore_limit && data_race(barn->nr_empty) >= MAX_EMPTY_SHEAVES)
+ return -E2BIG;
spin_lock_irqsave(&barn->lock, flags);
- if (!ignore_limit && barn->nr_empty >= MAX_EMPTY_SHEAVES) {
- ret = -E2BIG;
- } else {
- list_add(&sheaf->barn_list, &barn->sheaves_empty);
- barn->nr_empty++;
- }
+ list_add(&sheaf->barn_list, &barn->sheaves_empty);
+ barn->nr_empty++;
spin_unlock_irqrestore(&barn->lock, flags);
- return ret;
+ return 0;
}
static int barn_put_full_sheaf(struct node_barn *barn, struct slab_sheaf *sheaf,
bool ignore_limit)
{
unsigned long flags;
- int ret = 0;
+
+ /* we don't repeat the check under barn->lock as it's not critical */
+ if (!ignore_limit && data_race(barn->nr_full) >= MAX_FULL_SHEAVES)
+ return -E2BIG;
spin_lock_irqsave(&barn->lock, flags);
- if (!ignore_limit && barn->nr_full >= MAX_FULL_SHEAVES) {
- ret = -E2BIG;
- } else {
- list_add(&sheaf->barn_list, &barn->sheaves_full);
- barn->nr_full++;
- }
+ list_add(&sheaf->barn_list, &barn->sheaves_full);
+ barn->nr_full++;
spin_unlock_irqrestore(&barn->lock, flags);
- return ret;
+ return 0;
}
static struct slab_sheaf *barn_get_full_or_empty_sheaf(struct node_barn *barn)
@@ -2755,6 +2756,9 @@ static struct slab_sheaf *barn_get_full_or_empty_sheaf(struct node_barn *barn)
struct slab_sheaf *sheaf = NULL;
unsigned long flags;
+ if (!data_race(barn->nr_full) && !data_race(barn->nr_empty))
+ return NULL;
+
spin_lock_irqsave(&barn->lock, flags);
if (barn->nr_full) {
@@ -2785,9 +2789,12 @@ barn_replace_empty_sheaf(struct node_barn *barn, struct slab_sheaf *empty)
struct slab_sheaf *full = NULL;
unsigned long flags;
+ if (!data_race(barn->nr_full))
+ return NULL;
+
spin_lock_irqsave(&barn->lock, flags);
- if (barn->nr_full) {
+ if (likely(barn->nr_full)) {
full = list_first_entry(&barn->sheaves_full, struct slab_sheaf,
barn_list);
list_del(&full->barn_list);
@@ -2810,19 +2817,23 @@ barn_replace_full_sheaf(struct node_barn *barn, struct slab_sheaf *full)
struct slab_sheaf *empty;
unsigned long flags;
+ /* we don't repeat this check under barn->lock as it's not critical */
+ if (data_race(barn->nr_full) >= MAX_FULL_SHEAVES)
+ return ERR_PTR(-E2BIG);
+ if (!data_race(barn->nr_empty))
+ return ERR_PTR(-ENOMEM);
+
spin_lock_irqsave(&barn->lock, flags);
- if (barn->nr_full >= MAX_FULL_SHEAVES) {
- empty = ERR_PTR(-E2BIG);
- } else if (!barn->nr_empty) {
- empty = ERR_PTR(-ENOMEM);
- } else {
+ if (likely(barn->nr_empty)) {
empty = list_first_entry(&barn->sheaves_empty, struct slab_sheaf,
barn_list);
list_del(&empty->barn_list);
list_add(&full->barn_list, &barn->sheaves_full);
barn->nr_empty--;
barn->nr_full++;
+ } else {
+ empty = ERR_PTR(-ENOMEM);
}
spin_unlock_irqrestore(&barn->lock, flags);