OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [md/] [xor.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * xor.c : Multiple Devices driver for Linux
3
 *
4
 * Copyright (C) 1996, 1997, 1998, 1999, 2000,
5
 * Ingo Molnar, Matti Aarnio, Jakub Jelinek, Richard Henderson.
6
 *
7
 * Dispatch optimized RAID-5 checksumming functions.
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2, or (at your option)
12
 * any later version.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * (for example /usr/src/linux/COPYING); if not, write to the Free
16
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
 */
18
 
19
#define BH_TRACE 0
20
#include <linux/module.h>
21
#include <linux/raid/md.h>
22
#include <linux/raid/xor.h>
23
#include <asm/xor.h>
24
 
25
/* The xor routines to use.  */
26
static struct xor_block_template *active_template;
27
 
28
void
29
xor_block(unsigned int count, struct buffer_head **bh_ptr)
30
{
31
        unsigned long *p0, *p1, *p2, *p3, *p4;
32
        unsigned long bytes = bh_ptr[0]->b_size;
33
 
34
        p0 = (unsigned long *) bh_ptr[0]->b_data;
35
        p1 = (unsigned long *) bh_ptr[1]->b_data;
36
        if (count == 2) {
37
                active_template->do_2(bytes, p0, p1);
38
                return;
39
        }
40
 
41
        p2 = (unsigned long *) bh_ptr[2]->b_data;
42
        if (count == 3) {
43
                active_template->do_3(bytes, p0, p1, p2);
44
                return;
45
        }
46
 
47
        p3 = (unsigned long *) bh_ptr[3]->b_data;
48
        if (count == 4) {
49
                active_template->do_4(bytes, p0, p1, p2, p3);
50
                return;
51
        }
52
 
53
        p4 = (unsigned long *) bh_ptr[4]->b_data;
54
        active_template->do_5(bytes, p0, p1, p2, p3, p4);
55
}
56
 
57
/* Set of all registered templates.  */
58
static struct xor_block_template *template_list;
59
 
60
#define BENCH_SIZE (PAGE_SIZE)
61
 
62
static void
63
do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
64
{
65
        int speed;
66
        unsigned long now;
67
        int i, count, max;
68
 
69
        tmpl->next = template_list;
70
        template_list = tmpl;
71
 
72
        /*
73
         * Count the number of XORs done during a whole jiffy, and use
74
         * this to calculate the speed of checksumming.  We use a 2-page
75
         * allocation to have guaranteed color L1-cache layout.
76
         */
77
        max = 0;
78
        for (i = 0; i < 5; i++) {
79
                now = jiffies;
80
                count = 0;
81
                while (jiffies == now) {
82
                        mb();
83
                        tmpl->do_2(BENCH_SIZE, b1, b2);
84
                        mb();
85
                        count++;
86
                        mb();
87
                }
88
                if (count > max)
89
                        max = count;
90
        }
91
 
92
        speed = max * (HZ * BENCH_SIZE / 1024);
93
        tmpl->speed = speed;
94
 
95
        printk("   %-10s: %5d.%03d MB/sec\n", tmpl->name,
96
               speed / 1000, speed % 1000);
97
}
98
 
99
static int
100
calibrate_xor_block(void)
101
{
102
        void *b1, *b2;
103
        struct xor_block_template *f, *fastest;
104
 
105
        b1 = (void *) md__get_free_pages(GFP_KERNEL, 2);
106
        if (! b1) {
107
                printk("raid5: Yikes!  No memory available.\n");
108
                return -ENOMEM;
109
        }
110
        b2 = b1 + 2*PAGE_SIZE + BENCH_SIZE;
111
 
112
        printk(KERN_INFO "raid5: measuring checksumming speed\n");
113
        sti();
114
 
115
#define xor_speed(templ)        do_xor_speed((templ), b1, b2)
116
 
117
        XOR_TRY_TEMPLATES;
118
 
119
#undef xor_speed
120
 
121
        free_pages((unsigned long)b1, 2);
122
 
123
        fastest = template_list;
124
        for (f = fastest; f; f = f->next)
125
                if (f->speed > fastest->speed)
126
                        fastest = f;
127
 
128
#ifdef XOR_SELECT_TEMPLATE
129
        fastest = XOR_SELECT_TEMPLATE(fastest);
130
#endif
131
 
132
        active_template = fastest;
133
        printk("raid5: using function: %s (%d.%03d MB/sec)\n",
134
               fastest->name, fastest->speed / 1000, fastest->speed % 1000);
135
 
136
        return 0;
137
}
138
 
139
MD_EXPORT_SYMBOL(xor_block);
140
MODULE_LICENSE("GPL");
141
 
142
module_init(calibrate_xor_block);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.