Add patch SR-ext4-resize-mark-new-group-EXT_BG_INODE_ZEROED.patch
[ext4-patch-queue/an.git] / reduce-jbd2-stacksize
blob4426a871a627898b63e8a9abced5a82c7c3bf358
1 jbd2: Remove a large array of bh's from the stack of the checkpoint routine
3 jbd2_log_do_checkpoint()n is one of the kernel's largest stack users.
4 Move the array of buffer head's from the stack of jbd2_log_do_checkpoint()
5 to the in-core journal structure.
7 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
8 diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
9 index 02f9db1..6b7e06d 100644
10 --- a/fs/jbd2/checkpoint.c
11 +++ b/fs/jbd2/checkpoint.c
12 @@ -243,16 +243,14 @@ restart:
13         return ret;
14  }
16 -#define NR_BATCH       64
18  static void
19 -__flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
20 +__flush_batch(journal_t *journal, int *batch_count)
21  {
22         int i;
24 -       ll_rw_block(SWRITE, *batch_count, bhs);
25 +       ll_rw_block(SWRITE, *batch_count, journal->j_chkpt_bhs);
26         for (i = 0; i < *batch_count; i++) {
27 -               struct buffer_head *bh = bhs[i];
28 +               struct buffer_head *bh = journal->j_chkpt_bhs[i];
29                 clear_buffer_jwrite(bh);
30                 BUFFER_TRACE(bh, "brelse");
31                 __brelse(bh);
32 @@ -271,8 +269,7 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
33   * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
34   */
35  static int __process_buffer(journal_t *journal, struct journal_head *jh,
36 -                       struct buffer_head **bhs, int *batch_count,
37 -                       transaction_t *transaction)
38 +                           int *batch_count, transaction_t *transaction)
39  {
40         struct buffer_head *bh = jh2bh(jh);
41         int ret = 0;
42 @@ -319,14 +316,14 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
43                 get_bh(bh);
44                 J_ASSERT_BH(bh, !buffer_jwrite(bh));
45                 set_buffer_jwrite(bh);
46 -               bhs[*batch_count] = bh;
47 +               journal->j_chkpt_bhs[*batch_count] = bh;
48                 __buffer_relink_io(jh);
49                 jbd_unlock_bh_state(bh);
50                 transaction->t_chp_stats.cs_written++;
51                 (*batch_count)++;
52 -               if (*batch_count == NR_BATCH) {
53 +               if (*batch_count == JBD2_NR_BATCH) {
54                         spin_unlock(&journal->j_list_lock);
55 -                       __flush_batch(journal, bhs, batch_count);
56 +                       __flush_batch(journal, batch_count);
57                         ret = 1;
58                 }
59         }
60 @@ -382,7 +379,6 @@ restart:
61         if (journal->j_checkpoint_transactions == transaction &&
62                         transaction->t_tid == this_tid) {
63                 int batch_count = 0;
64 -               struct buffer_head *bhs[NR_BATCH];
65                 struct journal_head *jh;
66                 int retry = 0, err;
68 @@ -396,7 +392,7 @@ restart:
69                                 retry = 1;
70                                 break;
71                         }
72 -                       retry = __process_buffer(journal, jh, bhs, &batch_count,
73 +                       retry = __process_buffer(journal, jh, &batch_count,
74                                                  transaction);
75                         if (retry < 0 && !result)
76                                 result = retry;
77 @@ -413,7 +409,7 @@ restart:
78                                 spin_unlock(&journal->j_list_lock);
79                                 retry = 1;
80                         }
81 -                       __flush_batch(journal, bhs, &batch_count);
82 +                       __flush_batch(journal, &batch_count);
83                 }
85                 if (retry) {
86 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
87 index e70d657..d91310b 100644
88 --- a/fs/jbd2/journal.c
89 +++ b/fs/jbd2/journal.c
90 @@ -1472,7 +1472,9 @@ int jbd2_journal_destroy(journal_t *journal)
91         spin_lock(&journal->j_list_lock);
92         while (journal->j_checkpoint_transactions != NULL) {
93                 spin_unlock(&journal->j_list_lock);
94 +               mutex_lock(&journal->j_checkpoint_mutex);
95                 jbd2_log_do_checkpoint(journal);
96 +               mutex_unlock(&journal->j_checkpoint_mutex);
97                 spin_lock(&journal->j_list_lock);
98         }
100 diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
101 index b8b8744..e9dbaa6 100644
102 --- a/include/linux/jbd2.h
103 +++ b/include/linux/jbd2.h
104 @@ -686,6 +686,8 @@ jbd2_time_diff(unsigned long start, unsigned long end)
105         return end + (MAX_JIFFY_OFFSET - start);
108 +#define JBD2_NR_BATCH  64
110  /**
111   * struct journal_s - The journal_s type is the concrete type associated with
112   *     journal_t.
113 @@ -830,6 +832,14 @@ struct journal_s
114         struct mutex            j_checkpoint_mutex;
116         /*
117 +        * List of buffer heads used by the checkpoint routine.  This
118 +        * was moved from jbd2_log_do_checkpoint() to reduce stack
119 +        * usage.  Access to this array is controlled by the
120 +        * j_checkpoint_mutex.  [j_checkpoint_mutex]
121 +        */
122 +       struct buffer_head      *j_chkpt_bhs[JBD2_NR_BATCH];
123 +       
124 +       /*
125          * Journal head: identifies the first unused block in the journal.
126          * [j_state_lock]
127          */