/usr/src/kernel-patches/lustre/patches/raid6-merge-ios.patch is in linux-patch-lustre 1.8.5+dfsg-3ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | diff -pur linux-2.6.9.orig/drivers/md/raid6main.c linux-2.6.9/drivers/md/raid6main.c
--- linux-2.6.9.orig/drivers/md/raid6main.c 2008-01-10 13:51:32.000000000 +0800
+++ linux-2.6.9/drivers/md/raid6main.c 2008-01-10 13:52:20.000000000 +0800
@@ -956,6 +956,26 @@ static void add_stripe_bio (struct strip
}
}
+/*
+ * The whole idea is to collect all bio's and then issue them
+ * disk by disk to assist merging a bit -bzzz
+ */
+static void raid6_flush_bios(raid6_conf_t *conf, struct bio *bios[], int raid_disks)
+{
+ struct bio *bio, *nbio;
+ int i;
+
+ for (i = 0; i < raid_disks; i++) {
+ bio = bios[i];
+ while (bio) {
+ nbio = bio->bi_next;
+ bio->bi_next = NULL;
+ generic_make_request(bio);
+ bio = nbio;
+ }
+ bios[i] = NULL;
+ }
+}
/*
* handle_stripe - do things to a stripe.
@@ -975,7 +995,7 @@ static void add_stripe_bio (struct strip
*
*/
-static void handle_stripe(struct stripe_head *sh)
+static void handle_stripe(struct stripe_head *sh, struct bio *bios[])
{
raid6_conf_t *conf = sh->raid_conf;
int disks = conf->raid_disks;
@@ -1452,7 +1472,11 @@ static void handle_stripe(struct stripe_
bi->bi_size = STRIPE_SIZE;
bi->bi_next = NULL;
atomic_inc(&conf->out_reqs_in_queue);
- generic_make_request(bi);
+ if(bios) {
+ bi->bi_next = bios[i];
+ bios[i] = bi;
+ } else
+ generic_make_request(bi);
} else {
PRINTK("skip op %ld on disc %d for sector %llu\n",
bi->bi_rw, i, (unsigned long long)sh->sector);
@@ -1575,6 +1599,7 @@ static int make_request (request_queue_t
int sectors_per_chunk;
int stripes_per_chunk, sectors_per_block;
int sectors_per_stripe;
+ struct bio *bios[MD_SB_DISKS];
int i, j;
atomic_inc(&conf->in_reqs_in_queue);
@@ -1611,6 +1636,7 @@ static int make_request (request_queue_t
sector_div(block, sectors_per_block);
sectors = bi->bi_size >> 9;
+ memset(&bios, 0, sizeof(bios));
repeat:
stripe = block * (sectors_per_block / data_disks);
b_sector = stripe * data_disks;
@@ -1630,9 +1656,17 @@ static int make_request (request_queue_t
new_sector = raid6_compute_sector(r_sector, raid_disks,
data_disks, &dd_idx,
&pd_idx, conf);
- if (sh == NULL)
- sh = get_active_stripe(conf, new_sector, pd_idx,
- (bi->bi_rw&RWA_MASK));
+ if (sh == NULL) {
+ /* first, try to get stripe w/o blocking
+ * if we can't, then it's time to submit
+ * all collected bio's in order to free
+ * some space in the cache -bzzz */
+ sh = get_active_stripe(conf, new_sector, pd_idx, 1);
+ if (!sh && !(bi->bi_rw&RWA_MASK)) {
+ raid6_flush_bios(conf, bios, raid_disks);
+ sh = get_active_stripe(conf, new_sector, pd_idx, 0);
+ }
+ }
if (sh) {
add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
} else {
@@ -1653,7 +1687,7 @@ static int make_request (request_queue_t
if (sh) {
raid6_plug_device(conf);
- handle_stripe(sh);
+ handle_stripe(sh, bios);
release_stripe(sh);
sh = NULL;
}
@@ -1664,6 +1698,9 @@ static int make_request (request_queue_t
if(sectors > 0)
goto repeat;
+ /* now flush all bio's */
+ raid6_flush_bios(conf, bios, raid_disks);
+
spin_lock_irq(&conf->device_lock);
if (--bi->bi_phys_segments == 0) {
int bytes = bi->bi_size;
@@ -1719,7 +1756,7 @@ static int sync_request (mddev_t *mddev,
clear_bit(STRIPE_INSYNC, &sh->state);
spin_unlock(&sh->lock);
- handle_stripe(sh);
+ handle_stripe(sh, NULL);
release_stripe(sh);
return STRIPE_SECTORS;
@@ -1769,7 +1806,7 @@ static void raid6d (mddev_t *mddev)
handled++;
atomic_inc(&conf->handled_in_raid5d);
- handle_stripe(sh);
+ handle_stripe(sh, NULL);
release_stripe(sh);
spin_lock_irq(&conf->device_lock);
|