Root/target/linux/cns3xxx/patches-2.6.31/206-cns3xxx_raid_support.patch

1--- a/crypto/xor.c
2+++ b/crypto/xor.c
3@@ -25,6 +25,26 @@
4 /* The xor routines to use. */
5 static struct xor_block_template *active_template;
6 
7+#ifdef CONFIG_CNS3XXX_RAID
8+extern void do_cns_rdma_xorgen(unsigned int src_no, unsigned int bytes,
9+ void **bh_ptr, void *dst_ptr);
10+/**
11+ * xor_blocks - one pass xor
12+ * @src_count: source count
13+ * @bytes: length in bytes
14+ * @dest: dest
15+ * @srcs: srcs
16+ *
17+ * Desc:
18+ * 1. dest = xor(srcs[0...src_count-1]) within one calc
19+ * 2. don't care if dest also be placed in srcs list or not.
20+ */
21+void xor_blocks(unsigned int src_count, unsigned int bytes, void *dest,
22+ void **srcs)
23+{
24+ do_cns_rdma_xorgen(src_count, bytes, srcs, dest);
25+}
26+#else
27 void
28 xor_blocks(unsigned int src_count, unsigned int bytes, void *dest, void **srcs)
29 {
30@@ -51,6 +71,7 @@ xor_blocks(unsigned int src_count, unsig
31     p4 = (unsigned long *) srcs[3];
32     active_template->do_5(bytes, dest, p1, p2, p3, p4);
33 }
34+#endif /* CONFIG_CNS3XXX_RAID */
35 EXPORT_SYMBOL(xor_blocks);
36 
37 /* Set of all registered templates. */
38@@ -95,7 +116,11 @@ do_xor_speed(struct xor_block_template *
39            speed / 1000, speed % 1000);
40 }
41 
42+#ifdef CONFIG_CNS3XXX_RAID
43+int
44+#else
45 static int __init
46+#endif /* CONFIG_CNS3XXX_RAID */
47 calibrate_xor_blocks(void)
48 {
49     void *b1, *b2;
50@@ -139,7 +164,10 @@ calibrate_xor_blocks(void)
51             if (f->speed > fastest->speed)
52                 fastest = f;
53     }
54-
55+#ifdef CONFIG_CNS3XXX_RAID
56+ /* preferred */
57+ fastest = template_list;
58+#endif /* CONFIG_CNS3XXX_RAID */
59     printk(KERN_INFO "xor: using function: %s (%d.%03d MB/sec)\n",
60            fastest->name, fastest->speed / 1000, fastest->speed % 1000);
61 
62@@ -151,10 +179,20 @@ calibrate_xor_blocks(void)
63     return 0;
64 }
65 
66-static __exit void xor_exit(void) { }
67+#ifndef CONFIG_CNS3XXX_RAID
68+static __exit void xor_exit(void)
69+{
70+}
71+#endif /* ! CONFIG_CNS3XXX_RAID */
72 
73 MODULE_LICENSE("GPL");
74 
75+#ifdef CONFIG_CNS3XXX_RAID
76+/*
77+ * Calibrate in R5 init.
78+ */
79+#else
80 /* when built-in xor.o must initialize before drivers/md/md.o */
81 core_initcall(calibrate_xor_blocks);
82 module_exit(xor_exit);
83+#endif /* ! CONFIG_CNS3XXX_RAID */
84--- a/drivers/md/Makefile
85+++ b/drivers/md/Makefile
86@@ -17,7 +17,7 @@ raid6_pq-y += raid6algos.o raid6recov.o
87            raid6int8.o raid6int16.o raid6int32.o \
88            raid6altivec1.o raid6altivec2.o raid6altivec4.o \
89            raid6altivec8.o \
90- raid6mmx.o raid6sse1.o raid6sse2.o
91+ raid6mmx.o raid6sse1.o raid6sse2.o raid6cns.o
92 hostprogs-y += mktables
93 
94 # Note: link order is important. All raid personalities
95--- a/drivers/md/raid5.c
96+++ b/drivers/md/raid5.c
97@@ -1817,11 +1817,30 @@ static void compute_block_2(struct strip
98             compute_parity6(sh, UPDATE_PARITY);
99             return;
100         } else {
101+#ifdef CONFIG_CNS3XXX_RAID
102+ void *ptrs[disks];
103+
104+ count = 0;
105+ i = d0_idx;
106+ do {
107+ ptrs[count++] = page_address(sh->dev[i].page);
108+ i = raid6_next_disk(i, disks);
109+ if (i != dd_idx1 && i != dd_idx2 &&
110+ !test_bit(R5_UPTODATE, &sh->dev[i].flags))
111+ printk
112+ ("compute_2 with missing block %d/%d\n",
113+ count, i);
114+ } while (i != d0_idx);
115+
116+ raid6_dataq_recov(disks, STRIPE_SIZE, faila, ptrs);
117+#else
118+
119             /* We're missing D+Q; recompute D from P */
120             compute_block_1(sh, ((dd_idx1 == sh->qd_idx) ?
121                          dd_idx2 : dd_idx1),
122                     0);
123             compute_parity6(sh, UPDATE_PARITY); /* Is this necessary? */
124+#endif /* CONFIG_CNS3XXX_RAID */
125             return;
126         }
127     }
128@@ -5412,8 +5431,21 @@ static struct mdk_personality raid4_pers
129     .quiesce = raid5_quiesce,
130 };
131 
132+#ifdef CONFIG_CNS3XXX_RAID
133+extern int calibrate_xor_blocks(void);
134+#endif /* CONFIG_CNS3XXX_RAID */
135+
136 static int __init raid5_init(void)
137 {
138+
139+#ifdef CONFIG_CNS3XXX_RAID
140+ /* Just execute calibrate xor blocks */
141+ int e;
142+ e = calibrate_xor_blocks();
143+ if (e)
144+ return e;
145+#endif /* CONFIG_CNS3XXX_RAID */
146+
147     register_md_personality(&raid6_personality);
148     register_md_personality(&raid5_personality);
149     register_md_personality(&raid4_personality);
150--- a/drivers/md/raid6algos.c
151+++ b/drivers/md/raid6algos.c
152@@ -49,6 +49,9 @@ extern const struct raid6_calls raid6_al
153 extern const struct raid6_calls raid6_altivec2;
154 extern const struct raid6_calls raid6_altivec4;
155 extern const struct raid6_calls raid6_altivec8;
156+#ifdef CONFIG_CNS3XXX_RAID
157+extern const struct raid6_calls raid6_cns_raid;
158+#endif /* CONFIG_CNS3XXX_RAID */
159 
160 const struct raid6_calls * const raid6_algos[] = {
161     &raid6_intx1,
162@@ -78,6 +81,11 @@ const struct raid6_calls * const raid6_a
163     &raid6_altivec4,
164     &raid6_altivec8,
165 #endif
166+#ifdef CONFIG_CNS3XXX_RAID
167+ /* CNS3000 HW RAID acceleration */
168+ &raid6_cns_raid,
169+#endif /* CONFIG_CNS3XXX_RAID */
170+
171     NULL
172 };
173 
174@@ -125,7 +133,9 @@ int __init raid6_select_algo(void)
175         if ( !(*algo)->valid || (*algo)->valid() ) {
176             perf = 0;
177 
178+#ifndef CONFIG_CNS3XXX_RAID
179             preempt_disable();
180+#endif
181             j0 = jiffies;
182             while ( (j1 = jiffies) == j0 )
183                 cpu_relax();
184@@ -134,7 +144,9 @@ int __init raid6_select_algo(void)
185                 (*algo)->gen_syndrome(disks, PAGE_SIZE, dptrs);
186                 perf++;
187             }
188+#ifndef CONFIG_CNS3XXX_RAID
189             preempt_enable();
190+#endif
191 
192             if ( (*algo)->prefer > bestprefer ||
193                  ((*algo)->prefer == bestprefer &&
194--- /dev/null
195+++ b/drivers/md/raid6cns.c
196@@ -0,0 +1,38 @@
197+/*
198+ * raid6cns.c
199+ *
200+ * CNS3xxx xor & gen_syndrome functions
201+ *
202+ */
203+
204+#ifdef CONFIG_CNS3XXX_RAID
205+
206+#include <linux/raid/pq.h>
207+
208+extern void do_cns_rdma_gfgen(unsigned int src_no, unsigned int bytes, void **bh_ptr,
209+ void *p_dst, void *q_dst);
210+
211+/**
212+ * raid6_cnsraid_gen_syndrome - CNSRAID Syndrome Generate
213+ *
214+ * @disks: raid disks
215+ * @bytes: length
216+ * @ptrs: already arranged stripe ptrs,
217+ * disk0=[0], diskNNN=[disks-3],
218+ * P/Q=[z0+1] & [z0+2], or, [disks-2], [disks-1]
219+ */
220+static void raid6_cnsraid_gen_syndrome(int disks, size_t bytes, void **ptrs)
221+{
222+ do_cns_rdma_gfgen(disks - 2, bytes, ptrs, ptrs[disks-2], ptrs[disks-1]);
223+}
224+
225+const struct raid6_calls raid6_cns_raid = {
226+ raid6_cnsraid_gen_syndrome, /* callback */
227+ NULL, /* always valid */
228+ "CNS-RAID", /* name */
229+ 1 /* preferred: revise it to "0" to compare/compete with others algos */
230+};
231+
232+EXPORT_SYMBOL(raid6_cns_raid);
233+
234+#endif /* CONFIG_CNS3XXX_RAID */
235--- a/drivers/md/raid6recov.c
236+++ b/drivers/md/raid6recov.c
237@@ -20,6 +20,136 @@
238 
239 #include <linux/raid/pq.h>
240 
241+#ifdef CONFIG_CNS3XXX_RAID
242+#define R6_RECOV_PD 1
243+#define R6_RECOV_DD 2
244+#define R6_RECOV_DQ 3
245+extern void do_cns_rdma_gfgen_pd_dd_dq(unsigned int src_no, unsigned int bytes,
246+ void **bh_ptr, void *w1_dst,
247+ void *w2_dst, int pd_dd_qd,
248+ unsigned int w1_idx, unsigned int w2_idx,
249+ unsigned int *src_idx);
250+
251+/**
252+ * @disks: nr_disks
253+ * @bytes: len
254+ * @faila: 1st failed DD
255+ * @ptrs: ptrs by order {d0, d1, ..., da, ..., dn, P, Q}
256+ *
257+ * Desc:
258+ * new_read_ptrs = {d0, d1, ... dn, Q}
259+ * dd1 = faila
260+ * p_dst = P
261+ */
262+void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
263+{
264+ int cnt = 0;
265+ int count = 0;
266+ void *p_dst, *q;
267+ void *dd1_dst;
268+ void *new_read_ptrs[disks - 2];
269+ unsigned int read_idx[disks - 2];
270+
271+ q = ptrs[disks - 1];
272+ p_dst = ptrs[disks - 2];
273+ dd1_dst = ptrs[faila];
274+
275+ while (cnt < disks) {
276+ if (cnt != faila && cnt != disks - 2) {
277+ new_read_ptrs[count] = ptrs[cnt];
278+ read_idx[count] = cnt;
279+ count++;
280+ }
281+ cnt++;
282+ }
283+
284+ do_cns_rdma_gfgen_pd_dd_dq(disks - 2, bytes,
285+ new_read_ptrs, p_dst, dd1_dst,
286+ R6_RECOV_PD, disks - 1, faila + 1, read_idx);
287+}
288+
289+/**
290+ * @disks: nr_disks
291+ * @bytes: len
292+ * @faila: 1st failed DD
293+ * @failb: 2nd failed DD
294+ * @ptrs: ptrs by order {d0, d1, ..., da, ..., db, ..., dn, P, Q}
295+ *
296+ * Desc:
297+ * new_read_ptrs = {d0, d1, ... dn, P, Q}
298+ * dd1_dst = faila
299+ * dd2_dst = failb
300+ */
301+void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
302+ void **ptrs)
303+{
304+
305+ int cnt = 0;
306+ int count = 0;
307+ void *p, *q;
308+ void *dd1_dst, *dd2_dst;
309+ void *new_read_ptrs[disks - 2];
310+ unsigned int read_idx[disks - 2];
311+
312+ q = ptrs[disks - 1];
313+ p = ptrs[disks - 2];
314+ dd1_dst = ptrs[faila];
315+ dd2_dst = ptrs[failb];
316+
317+ while (cnt < disks) {
318+ if (cnt != faila && cnt != failb) {
319+ new_read_ptrs[count] = ptrs[cnt];
320+ read_idx[count] = cnt;
321+ count++;
322+ }
323+ cnt++;
324+ }
325+
326+ do_cns_rdma_gfgen_pd_dd_dq(disks - 2, bytes,
327+ new_read_ptrs, dd1_dst, dd2_dst,
328+ R6_RECOV_DD, faila + 1, failb + 1, read_idx);
329+}
330+
331+/**
332+ * @disks: nr_disks
333+ * @bytes: len
334+ * @faila: 1st failed DD
335+ * @ptrs: ptrs by order {d0, d1, ..., da, ..., dn, P, Q}
336+ *
337+ * Desc:
338+ * new_read_ptrs = {d0, d1, ... dn, P}
339+ * dd1 = faila
340+ * q_dst = Q
341+ */
342+void raid6_dataq_recov(int disks, size_t bytes, int faila, void **ptrs)
343+{
344+ int cnt = 0;
345+ int count = 0;
346+ void *q_dst, *p;
347+ void *dd1_dst;
348+ void *new_read_ptrs[disks - 2];
349+ unsigned int read_idx[disks - 2];
350+
351+ p = ptrs[disks - 2];
352+ q_dst = ptrs[disks - 1];
353+ dd1_dst = ptrs[faila];
354+
355+ while (cnt < disks) {
356+ if (cnt != faila && cnt != disks - 1) {
357+ new_read_ptrs[count] = ptrs[cnt];
358+ read_idx[count] = cnt;
359+ count++;
360+ }
361+ cnt++;
362+ }
363+
364+ do_cns_rdma_gfgen_pd_dd_dq(disks - 2, bytes,
365+ new_read_ptrs, dd1_dst, q_dst,
366+ R6_RECOV_DQ, faila + 1, disks, read_idx);
367+}
368+
369+#else /* CONFIG_CNS3XXX_RAID
370+
371 /* Recover two failed data blocks. */
372 void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
373                void **ptrs)
374@@ -96,6 +226,7 @@ void raid6_datap_recov(int disks, size_t
375     }
376 }
377 EXPORT_SYMBOL_GPL(raid6_datap_recov);
378+#endif /* CONFIG_CNS3XXX_RAID */
379 
380 #ifndef __KERNEL__
381 /* Testing only */
382--- a/include/linux/raid/pq.h
383+++ b/include/linux/raid/pq.h
384@@ -100,6 +100,9 @@ void raid6_2data_recov(int disks, size_t
385 void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
386 void raid6_dual_recov(int disks, size_t bytes, int faila, int failb,
387               void **ptrs);
388+#ifdef CONFIG_CNS3XXX_RAID
389+void raid6_dataq_recov(int disks, size_t bytes, int faila, void **ptrs);
390+#endif /* CONFIG_CNS3XXX_RAID */
391 
392 /* Some definitions to allow code to be compiled for testing in userspace */
393 #ifndef __KERNEL__
394--- a/include/linux/raid/xor.h
395+++ b/include/linux/raid/xor.h
396@@ -1,7 +1,11 @@
397 #ifndef _XOR_H
398 #define _XOR_H
399 
400+#ifdef CONFIG_CNS3XXX_RAID
401+#define MAX_XOR_BLOCKS 32
402+#else
403 #define MAX_XOR_BLOCKS 4
404+#endif /* CONFIG_CNS3XXX_RAID */
405 
406 extern void xor_blocks(unsigned int count, unsigned int bytes,
407     void *dest, void **srcs);
408--- a/mm/mempool.c
409+++ b/mm/mempool.c
410@@ -250,6 +250,28 @@ repeat_alloc:
411 }
412 EXPORT_SYMBOL(mempool_alloc);
413 
414+#ifdef CONFIG_CNS3XXX_RAID
415+/**
416+ * acs_mempool_alloc - allocate an element from a specific memory pool
417+ * @pool: pointer to the memory pool which was allocated via
418+ * mempool_create().
419+ *
420+ * this function differs from mempool_alloc by directly allocating an element
421+ * from @pool without calling @pool->alloc().
422+ */
423+void *acs_mempool_alloc(mempool_t * pool)
424+{
425+ unsigned long flags;
426+ void *element = NULL;
427+
428+ spin_lock_irqsave(&pool->lock, flags);
429+ if (likely(pool->curr_nr))
430+ element = remove_element(pool);
431+ spin_unlock_irqrestore(&pool->lock, flags);
432+ return element;
433+}
434+#endif /* CONFIG_CNS3XXX_RAID */
435+
436 /**
437  * mempool_free - return an element to the pool.
438  * @element: pool element pointer.
439

Archive Download this file



interactive