Thread (44 messages) 44 messages, 11 authors, 2009-02-13

Re: [PATCH 09/18] md/raid6: remove expectation that Q device is immediately after P device.

From: Dan Williams <hidden>
Date: 2009-02-13 22:19:43

On Thu, Feb 12, 2009 at 9:56 AM, Andre Noll [off-list ref] wrote:
On 14:10, NeilBrown wrote:
quoted
-static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int previous);
+static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int previous,
+                        int *qd_idx);
That's a bit ugly, isn't it? The function computes both the p index
and the q index which is not obvious from its name. Also, the p index
is the return value and the q index is returned via a pointer which
is a bit unsymmetric.

static void get_parity_indices(sector_t stripe, raid5_conf_t *conf, int previous,
                                int *pd_idx, int *qd_idx);

perhaps?
quoted
+     /* Note that unlike RAID-5, the ordering of the disks matters greatly.*/
+     /* FIX: Is this ordering of drives even remotely optimal? */
+     count = 0;
+     i = d0_idx;
+     do {
+             if (i == sh->pd_idx)
+                     ptrs[disks-2] = page_address(sh->dev[i].page);
+             else if (i == sh->qd_idx)
+                     ptrs[disks-1] = page_address(sh->dev[i].page);
+             else {
                      ptrs[count++] = page_address(sh->dev[i].page);
-                     if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags))
+                     if (!test_bit(R5_UPTODATE, &sh->dev[i].flags))
                              printk("block %d/%d not uptodate on parity calc\n", i,count);
-                     i = raid6_next_disk(i, disks);
-             } while ( i != d0_idx );
-//           break;
-//   }
+             }
+             i = raid6_next_disk(i, disks);
+     } while (i != d0_idx);
+     BUG_ON(count+2 != disks);
Isn't it really dangerous to ignore a dirty stripe head during parity
calculation? I understand that compute_parity6() does not have a
return value and that dirty stripe heads have always been ignored by
compute_parity6(). But it looks much saner to fail in this case.

BTW, the printk lacks a KERN_ERR.
quoted
+     /**** FIX THIS: This could be very bad if disks is close to 256 ****/
+     void *ptrs[disks];
How serious is this? It's probably not a problem for version 0.90
superblocks as one can't have more than 26 disks. OTOH, for version
1 superblocks we might end up using up to 2K of stack space on 64
bit machines.
This is ok in recent kernels because we perform raid calculations in
raid5d or md_do_sync where we have our own stack.  However, with raid6
acceleration we also want to convert dma addresses on the stack which
means the calculation needs double the amount of space.
Would it be a reasonable to always allocate 26 pointers, say, and
fall back to malloc() if this turns out to be too small?
Even a GFP_ATOMIC allocation may fail and we would always be
allocating in the > 26 disks case.  The worst case scenario is
actually 4K stacks on a raid6 acceleration enabled 32-bit system with
64-bit dma addresses.  This configuration would require 3K of stack to
start a 256 disk parity calculation, but that should still be ok given
we have our own thread.

Regards,
Dan
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help