Whamcloud - gitweb
land b1_5 onto HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / raid5-merge-ios.patch
1 Merge IO requests to try and get larger requests on underlying drives.
2
3 Index: linux-2.6.9/drivers/md/raid5.c
4 ===================================================================
5 --- linux-2.6.9.orig/drivers/md/raid5.c 2006-05-22 00:10:04.000000000 +0400
6 +++ linux-2.6.9/drivers/md/raid5.c      2006-05-22 00:10:06.000000000 +0400
7 @@ -934,6 +934,26 @@ static void add_stripe_bio (struct strip
8         }
9  }
10  
11 +/*
12 + * The whole idea is to collect all bio's and then issue them
13 + * disk by disk to assist merging a bit -bzzz
14 + */
15 +static void raid5_flush_bios(raid5_conf_t *conf, struct bio *bios[], int raid_disks)
16 +{
17 +       struct bio *bio, *nbio;
18 +       int i;
19 +
20 +       for (i = 0; i < raid_disks; i++) {
21 +               bio = bios[i];
22 +               while (bio) {
23 +                       nbio = bio->bi_next;
24 +                       bio->bi_next = NULL;
25 +                       generic_make_request(bio);
26 +                       bio = nbio;
27 +               }
28 +               bios[i] = NULL;
29 +       }
30 +}
31  
32  /*
33   * handle_stripe - do things to a stripe.
34 @@ -953,7 +973,7 @@ static void add_stripe_bio (struct strip
35   *
36   */
37   
38 -static void handle_stripe(struct stripe_head *sh)
39 +static void handle_stripe(struct stripe_head *sh, struct bio *bios[])
40  {
41         raid5_conf_t *conf = sh->raid_conf;
42         int disks = conf->raid_disks;
43 @@ -1376,7 +1396,11 @@ static void handle_stripe(struct stripe_
44                         bi->bi_size = STRIPE_SIZE;
45                         bi->bi_next = NULL;
46                         atomic_inc(&conf->out_reqs_in_queue);
47 -                       generic_make_request(bi);
48 +                       if (bios) {
49 +                               bi->bi_next = bios[i];
50 +                               bios[i] = bi;
51 +                       } else
52 +                               generic_make_request(bi);
53                 } else {
54                         PRINTK("skip op %ld on disc %d for sector %llu\n",
55                                 bi->bi_rw, i, (unsigned long long)sh->sector);
56 @@ -1501,6 +1525,7 @@ static int make_request (request_queue_t
57         int sectors_per_chunk = conf->chunk_size >> 9;
58         int stripes_per_chunk, sectors_per_block;
59         int sectors_per_stripe;
60 +       struct bio *bios[MD_SB_DISKS];
61         int i, j;
62  
63         atomic_inc(&conf->in_reqs_in_queue);
64 @@ -1530,6 +1555,7 @@ static int make_request (request_queue_t
65         sector_div(block, sectors_per_block);
66         sectors = bi->bi_size >> 9;
67  
68 +       memset(&bios, 0, sizeof(bios));
69  repeat:
70         stripe = block * sectors_per_block / data_disks;
71         b_sector = stripe * data_disks;
72 @@ -1549,9 +1575,17 @@ repeat:
73                         new_sector = raid5_compute_sector(r_sector, raid_disks,
74                                                         data_disks, &dd_idx, 
75                                                         &pd_idx, conf);
76 -                       if (sh == NULL)
77 -                               sh = get_active_stripe(conf, new_sector, pd_idx,
78 -                                                       (bi->bi_rw&RWA_MASK));
79 +                       if (sh == NULL) {
80 +                               /* first, try to get stripe w/o blocking
81 +                                * if we can't, then it's time to submit
82 +                                * all collected bio's in order to free
83 +                                * some space in the cache -bzzz */
84 +                               sh = get_active_stripe(conf, new_sector, pd_idx, 1);
85 +                               if (!sh && !(bi->bi_rw&RWA_MASK)) {
86 +                                       raid5_flush_bios(conf, bios, raid_disks);
87 +                                       sh = get_active_stripe(conf, new_sector, pd_idx, 0);
88 +                               }
89 +                       }
90                         if (sh) {
91                                 add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
92                         } else {
93 @@ -1571,7 +1605,7 @@ repeat:
94                 }
95                 if (sh) {
96                         raid5_plug_device(conf);
97 -                       handle_stripe(sh);
98 +                       handle_stripe(sh, bios);
99                         release_stripe(sh);
100                         sh = NULL;
101                 }
102 @@ -1581,6 +1615,9 @@ repeat:
103         if (sectors > 0)
104                 goto repeat;
105  
106 +       /* now flush all bio's */
107 +       raid5_flush_bios(conf, bios, raid_disks);
108 +
109         spin_lock_irq(&conf->device_lock);
110         if (--bi->bi_phys_segments == 0) {
111                 int bytes = bi->bi_size;
112 @@ -1636,7 +1673,7 @@ static int sync_request (mddev_t *mddev,
113         clear_bit(STRIPE_INSYNC, &sh->state);
114         spin_unlock(&sh->lock);
115  
116 -       handle_stripe(sh);
117 +       handle_stripe(sh, NULL);
118         release_stripe(sh);
119  
120         return STRIPE_SECTORS;
121 @@ -1685,7 +1722,7 @@ static void raid5d (mddev_t *mddev)
122                 
123                 handled++;
124                 atomic_inc(&conf->handled_in_raid5d);
125 -               handle_stripe(sh);
126 +               handle_stripe(sh, NULL);
127                 release_stripe(sh);
128  
129                 spin_lock_irq(&conf->device_lock);