jbd2: get rid of open coded allocation retry loop
authorMichal Hocko <mhocko@suse.cz>
Mon, 15 Jun 2015 19:45:58 +0000 (15:45 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 15 Jun 2015 19:45:58 +0000 (15:45 -0400)
insert_revoke_hash does an open coded endless allocation loop if
journal_oom_retry is true. It doesn't implement any allocation fallback
strategy between the retries, though. The memory allocator doesn't know
about the never fail requirement so it cannot potentially help to move
on with the allocation (e.g. use memory reserves).

Get rid of the retry loop and use __GFP_NOFAIL instead. We will lose the
debugging message but I am not sure it is anyhow helpful.

Do the same for journal_alloc_journal_head which is doing a similar
thing.

Signed-off-by: Michal Hocko <mhocko@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/jbd2/journal.c
fs/jbd2/revoke.c

index 5804466b57858016b7be088a3cfc2882fb443753..179d7d8733f2c1bc19da65e66b2698e7a785e17f 100644 (file)
@@ -2377,10 +2377,8 @@ static struct journal_head *journal_alloc_journal_head(void)
        if (!ret) {
                jbd_debug(1, "out of memory for journal_head\n");
                pr_notice_ratelimited("ENOMEM in %s, retrying.\n", __func__);
-               while (!ret) {
-                       yield();
-                       ret = kmem_cache_zalloc(jbd2_journal_head_cache, GFP_NOFS);
-               }
+               ret = kmem_cache_zalloc(jbd2_journal_head_cache,
+                               GFP_NOFS | __GFP_NOFAIL);
        }
        return ret;
 }
index 14214da80eb8ea5d781389ed5ff3b1e373f4e7b4..0abf2e7f725beb70135a4b65f90f6ada6f14134d 100644 (file)
@@ -141,11 +141,13 @@ static int insert_revoke_hash(journal_t *journal, unsigned long long blocknr,
 {
        struct list_head *hash_list;
        struct jbd2_revoke_record_s *record;
+       gfp_t gfp_mask = GFP_NOFS;
 
-repeat:
-       record = kmem_cache_alloc(jbd2_revoke_record_cache, GFP_NOFS);
+       if (journal_oom_retry)
+               gfp_mask |= __GFP_NOFAIL;
+       record = kmem_cache_alloc(jbd2_revoke_record_cache, gfp_mask);
        if (!record)
-               goto oom;
+               return -ENOMEM;
 
        record->sequence = seq;
        record->blocknr = blocknr;
@@ -154,13 +156,6 @@ repeat:
        list_add(&record->hash, hash_list);
        spin_unlock(&journal->j_revoke_lock);
        return 0;
-
-oom:
-       if (!journal_oom_retry)
-               return -ENOMEM;
-       jbd_debug(1, "ENOMEM in %s, retrying\n", __func__);
-       yield();
-       goto repeat;
 }
 
 /* Find a revoke record in the journal's hash table. */