[PATCH] PowerPC: Fix num_cpus calculation in smp_call_function_map()
[POWERPC]: Fix num_cpus calculation in smp_call_function_map(). In smp_call_function_map(), num_cpus is set to the number of online CPUs minus one. However, if the CPU mask does not include all CPUs (except the one we're running on), the routine will hang in the first while() loop until the 8 second timeout occurs. The num_cpus should be set to the number of CPUs specified in the mask passed into the routine, after we've made any modifications to the mask. With this change, we can also get rid of the call to cpus_empty() and avoid adding another pass through the bitmask. Signed-off-by: Kevin Corry <[EMAIL PROTECTED]> Signed-off-by: Carl Love <[EMAIL PROTECTED]> Index: linux-2.6.23-rc1/arch/powerpc/kernel/smp.c === --- linux-2.6.23-rc1.orig/arch/powerpc/kernel/smp.c +++ linux-2.6.23-rc1/arch/powerpc/kernel/smp.c @@ -212,11 +212,6 @@ int smp_call_function_map(void (*func) ( atomic_set(&data.finished, 0); spin_lock(&call_lock); - /* Must grab online cpu count with preempt disabled, otherwise -* it can change. */ - num_cpus = num_online_cpus() - 1; - if (!num_cpus) - goto done; /* remove 'self' from the map */ if (cpu_isset(smp_processor_id(), map)) @@ -224,7 +219,9 @@ int smp_call_function_map(void (*func) ( /* sanity check the map, remove any non-online processors. */ cpus_and(map, map, cpu_online_map); - if (cpus_empty(map)) + + num_cpus = cpus_weight(map); + if (!num_cpus) goto done; call_data = &data; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] powerpc: change topology_init() to a subsys_initcall
Hi Michael, On Wed May 2 2007 8:11 pm, Michael Ellerman wrote: > On Wed, 2007-05-02 at 12:11 -0500, Kevin Corry wrote: > > Change the powerpc version of topology_init() from an __initcall to > > a subsys_initcall to match all other architectures. > > > > Signed-off-by: Kevin Corry <[EMAIL PROTECTED]> > > > > Index: linux-2.6.21/arch/powerpc/kernel/sysfs.c > > === > > --- linux-2.6.21.orig/arch/powerpc/kernel/sysfs.c > > +++ linux-2.6.21/arch/powerpc/kernel/sysfs.c > > @@ -498,4 +498,4 @@ static int __init topology_init(void) > > > > return 0; > > } > > -__initcall(topology_init); > > +subsys_initcall(topology_init); > > topology_init() depends on the register_one_node() stuff being > available, which relies on register_node_type() being called AFAICT - > which is a postcore_initcall(). So that's OK. > > It also creates sysfs files, which is OK because long before initcalls > run vfs_caches_init() called mnt_init() which called sysfs_init(). > > Just to be super safe it'd be good to diff your sysfs before and after > the change. But assuming that show's nothing this looks fine to me. I booted with and without this patch applied, and the file listings of /sys on both kernels show no differences (other than timestamps). Thanks for the feedback. -- Kevin Corry [EMAIL PROTECTED] http://www.ibm.com/linux/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] powerpc: add smp_call_function_single()
Add an smp_call_function_single() to the powerpc architecture. Since this is very similar to the existing smp_call_function() routine, the common portions have been split out into __smp_call_function(). Since the spin_lock(&call_lock) was moved to __smp_call_function(), smp_call_function() now explicitly calls preempt_disable() before getting the count of online CPUs. Signed-off-by: Kevin Corry <[EMAIL PROTECTED]> Index: linux-2.6.21/arch/powerpc/kernel/smp.c === --- linux-2.6.21.orig/arch/powerpc/kernel/smp.c +++ linux-2.6.21/arch/powerpc/kernel/smp.c @@ -175,26 +175,11 @@ static struct call_data_struct { /* delay of at least 8 seconds */ #define SMP_CALL_TIMEOUT 8 -/* - * This function sends a 'generic call function' IPI to all other CPUs - * in the system. - * - * [SUMMARY] Run a function on all other CPUs. - * The function to run. This must be fast and non-blocking. - * An arbitrary pointer to pass to the function. - * currently unused. - * If true, wait (atomically) until function has completed on other CPUs. - * [RETURNS] 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have executed. - * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ -int smp_call_function (void (*func) (void *info), void *info, int nonatomic, - int wait) -{ +static int __smp_call_function(void (*func)(void *info), void *info, + int wait, int target_cpu, int num_cpus) +{ struct call_data_struct data; - int ret = -1, cpus; + int ret = -1; u64 timeout; /* Can deadlock when called with interrupts disabled */ @@ -211,40 +196,33 @@ int smp_call_function (void (*func) (voi atomic_set(&data.finished, 0); spin_lock(&call_lock); - /* Must grab online cpu count with preempt disabled, otherwise -* it can change. */ - cpus = num_online_cpus() - 1; - if (!cpus) { - ret = 0; - goto out; - } call_data = &data; smp_wmb(); /* Send a message to all other CPUs and wait for them to respond */ - smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); + smp_ops->message_pass(target_cpu, PPC_MSG_CALL_FUNCTION); timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec; /* Wait for response */ - while (atomic_read(&data.started) != cpus) { + while (atomic_read(&data.started) != num_cpus) { HMT_low(); if (get_tb() >= timeout) { - printk("smp_call_function on cpu %d: other cpus not " - "responding (%d)\n", smp_processor_id(), - atomic_read(&data.started)); + printk("%s on cpu %d: other cpus not " + "responding (%d)\n", __FUNCTION__, + smp_processor_id(), atomic_read(&data.started)); debugger(NULL); goto out; } } if (wait) { - while (atomic_read(&data.finished) != cpus) { + while (atomic_read(&data.finished) != num_cpus) { HMT_low(); if (get_tb() >= timeout) { - printk("smp_call_function on cpu %d: other " - "cpus not finishing (%d/%d)\n", - smp_processor_id(), + printk("%s on cpu %d: other cpus " + "not finishing (%d/%d)\n", + __FUNCTION__, smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started)); debugger(NULL); @@ -262,8 +240,74 @@ int smp_call_function (void (*func) (voi return ret; } +/* + * This function sends a 'generic call function' IPI to all other CPUs + * in the system. + * + * [SUMMARY] Run a function on all other CPUs. + * The function to run. This must be fast and non-blocking. + * An arbitrary pointer to pass to the function. + * currently unused. + * If true, wait (atomically) until function has completed on other CPUs. + * [RETURNS] 0 on success, else a negative status code. Does not return until + * remote CPUs are nearly ready to execute <> or are or have executed. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler o
[PATCH 2/2] powerpc: change topology_init() to a subsys_initcall
Change the powerpc version of topology_init() from an __initcall to a subsys_initcall to match all other architectures. Signed-off-by: Kevin Corry <[EMAIL PROTECTED]> Index: linux-2.6.21/arch/powerpc/kernel/sysfs.c === --- linux-2.6.21.orig/arch/powerpc/kernel/sysfs.c +++ linux-2.6.21/arch/powerpc/kernel/sysfs.c @@ -498,4 +498,4 @@ static int __init topology_init(void) return 0; } -__initcall(topology_init); +subsys_initcall(topology_init); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/2] powerpc: perfmon2 prereqs
Hi, This is a repost of a couple patches I posted about a month ago related to porting perfmon2 to powerpc. I wanted to see if there were any further comments on these patches, and also wanted to ask if these should be submitted separately to the ppc kernel maintainers, or if they should be kept with the perfmon2 patches until those are submitted. The first patch adds an smp_call_function_single() routine for powerpc. In 2.6.21, there's a prototype for this routine in include/linux/smp.h, and it is implemented on i386, ia64, and x86-64. Since this routine is very similar to the existing smp_call_function() routine, the common portions have been pulled out into __smp_call_function(). Perfmon2 uses this unload a context that's loaded on a CPU other than the one that's performing the close-context routine. The second patch changes the powerpc version of topology_init() from an __initcall to a subsys_initcall, which matches the definition of topology_init() on all other architectures. Perfmon2's initialization is done as a subsys_initcall, but it fails to set up its sysfs information if topology_init() has not yet run. Changing perfmon2 to an __initcall() was discussed, but we came to the conclusion that this would not work because the perfmon2 core must be initialized before any of its sub-modules. These sub-modules are located in arch/*/perfmon/, and thus if they are built statically they would run their module_init routines before the perfmon2 core ran its __initcall routine. We have been running tests with these patches for the last few weeks on Cell and Power5 systems without any problems. Thanks, -- Kevin Corry [EMAIL PROTECTED] http://www.ibm.com/linux/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Questions about porting perfmon2 to powerpc
On Thu April 5 2007 6:04 pm, Benjamin Herrenschmidt wrote: > On Thu, 2007-04-05 at 14:55 -0500, Kevin Corry wrote: > > First, the stock 2.6.20 kernel has a prototype in include/linux/smp.h for > > a function called smp_call_function_single(). However, this routine is > > only implemented on i386, x86_64, ia64, and mips. Perfmon2 apparently > > needs to call this to run a function on a specific CPU. Powerpc provides > > an smp_call_function() routine to run a function on all active CPUs, so I > > used that as a basis to add an smp_call_function_single() routine. I've > > included the patch below and was wondering if it looked like a sane > > approach. > > We should do better... it will require some backend work for the various > supported PICs though. I've always wanted to look into doing a > smp_call_function_cpumask in fact :-) I was actually wondering about that myself today. It would seem like an smp_call_function() that takes a CPU mask would be much more flexible than either the current version or the new one that I proposed. However, that was a little more hacking that I was willing to do today on powerpc architecture code. :) > > Next, we ran into a problem related to Perfmon2 initialization and sysfs. > > The problem turned out to be that the powerpc version of topology_init() > > is defined as an __initcall() routine, but Perfmon2's initialization is > > done as a subsys_initcall() routine. Thus, Perfmon2 tries to initialize > > its sysfs information before some of the powerpc cpu information has been > > initialized. However, on all other architectures, topology_init() is > > defined as a subsys_initcall() routine, so this problem was not seen on > > any other platforms. Changing the powerpc version of topology_init() to a > > subsys_initcall() seems to have fixed the bug. However, I'm not sure if > > that is going to cause problems elsewhere in the powerpc code. I've > > included the patch below (after the smp-call-function-single patch). Does > > anyone know if this change is safe, or if there was a specific reason > > that topology_init() was left as an __initcall() on powerpc? > > It would make sense to follow what other archs do. Note that if both > perfmon and topology_init are subsys_initcall, that is on the same > level, it's still a bit hairy to expect one to be called before the > other... I wondered that as well, but based on what Arnd posted earlier (presumably about the kernel linking order), the topology_init() call, which is in the arch/ top-level directory, should occur before pfm_init(), which is in perfmon/, even if both are in the same initcall level. Thanks, -- Kevin Corry [EMAIL PROTECTED] http://www.ibm.com/linux/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Questions about porting perfmon2 to powerpc
On Thu April 5 2007 3:32 pm, Kevin Corry wrote: > On Thu April 5 2007 3:08 pm, Arnd Bergmann wrote: > > On Thursday 05 April 2007, Kevin Corry wrote: > > > First, the stock 2.6.20 kernel has a prototype in include/linux/smp.h > > > for a function called smp_call_function_single(). However, this routine > > > is only implemented on i386, x86_64, ia64, and mips. Perfmon2 > > > apparently needs to call this to run a function on a specific CPU. > > > Powerpc provides an smp_call_function() routine to run a function on > > > all active CPUs, so I used that as a basis to add an > > > smp_call_function_single() routine. I've included the patch below and > > > was wondering if it looked like a sane approach. > > > > The function itself looks good, but since it's very similar to the > > existing smp_call_function(), you should probably try to share some of > > the code, e.g. by making a helper function that gets an argument to > > decide whether to run on a specific CPU or on all CPUs. > > Ok. I'll see what I can come up with and post another patch today or > tomorrow. Here's a new version that adds smp_call_function_single(), and moves the code that's shared with smp_call_function() to __smp_call_function(). Thanks, -- Kevin Corry [EMAIL PROTECTED] http://www.ibm.com/linux/ Add an smp_call_function_single() to the powerpc architecture. Since this is very similar to the existing smp_call_function() routine, the common portions have been split out into __smp_call_function(). Since the spin_lock(&call_lock) was moved to __smp_call_function(), smp_call_function() now explicitly calls preempt_disable() before getting the count of online CPUs. Signed-off-by: Kevin Corry <[EMAIL PROTECTED]> Index: linux-2.6.20-arnd3-perfmon/arch/powerpc/kernel/smp.c === --- linux-2.6.20-arnd3-perfmon.orig/arch/powerpc/kernel/smp.c +++ linux-2.6.20-arnd3-perfmon/arch/powerpc/kernel/smp.c @@ -198,26 +198,11 @@ static struct call_data_struct { /* delay of at least 8 seconds */ #define SMP_CALL_TIMEOUT 8 -/* - * This function sends a 'generic call function' IPI to all other CPUs - * in the system. - * - * [SUMMARY] Run a function on all other CPUs. - * The function to run. This must be fast and non-blocking. - * An arbitrary pointer to pass to the function. - * currently unused. - * If true, wait (atomically) until function has completed on other CPUs. - * [RETURNS] 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have executed. - * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ -int smp_call_function (void (*func) (void *info), void *info, int nonatomic, - int wait) -{ +static int __smp_call_function(void (*func)(void *info), void *info, + int wait, int target_cpu, int num_cpus) +{ struct call_data_struct data; - int ret = -1, cpus; + int ret = -1; u64 timeout; /* Can deadlock when called with interrupts disabled */ @@ -234,40 +219,33 @@ int smp_call_function (void (*func) (voi atomic_set(&data.finished, 0); spin_lock(&call_lock); - /* Must grab online cpu count with preempt disabled, otherwise -* it can change. */ - cpus = num_online_cpus() - 1; - if (!cpus) { - ret = 0; - goto out; - } call_data = &data; smp_wmb(); /* Send a message to all other CPUs and wait for them to respond */ - smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); + smp_ops->message_pass(target_cpu, PPC_MSG_CALL_FUNCTION); timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec; /* Wait for response */ - while (atomic_read(&data.started) != cpus) { + while (atomic_read(&data.started) != num_cpus) { HMT_low(); if (get_tb() >= timeout) { - printk("smp_call_function on cpu %d: other cpus not " - "responding (%d)\n", smp_processor_id(), - atomic_read(&data.started)); + printk("%s on cpu %d: other cpus not " + "responding (%d)\n", __FUNCTION__, + smp_processor_id(), atomic_read(&data.started)); debugger(NULL); goto out; } } if (wait) { - while (atomic_read(&data.finished) != cpus) { + while (atomic_read(&data.
Re: Questions about porting perfmon2 to powerpc
On Thu April 5 2007 3:08 pm, Arnd Bergmann wrote: > On Thursday 05 April 2007, Kevin Corry wrote: > > First, the stock 2.6.20 kernel has a prototype in include/linux/smp.h for > > a function called smp_call_function_single(). However, this routine is > > only implemented on i386, x86_64, ia64, and mips. Perfmon2 apparently > > needs to call this to run a function on a specific CPU. Powerpc provides > > an smp_call_function() routine to run a function on all active CPUs, so I > > used that as a basis to add an smp_call_function_single() routine. I've > > included the patch below and was wondering if it looked like a sane > > approach. > > The function itself looks good, but since it's very similar to the existing > smp_call_function(), you should probably try to share some of the code, > e.g. by making a helper function that gets an argument to decide whether > to run on a specific CPU or on all CPUs. Ok. I'll see what I can come up with and post another patch today or tomorrow. > > Next, we ran into a problem related to Perfmon2 initialization and sysfs. > > The problem turned out to be that the powerpc version of topology_init() > > is defined as an __initcall() routine, but Perfmon2's initialization is > > done as a subsys_initcall() routine. Thus, Perfmon2 tries to initialize > > its sysfs information before some of the powerpc cpu information has been > > initialized. However, on all other architectures, topology_init() is > > defined as a subsys_initcall() routine, so this problem was not seen on > > any other platforms. Changing the powerpc version of topology_init() to a > > subsys_initcall() seems to have fixed the bug. However, I'm not sure if > > that is going to cause problems elsewhere in the powerpc code. I've > > included the patch below (after the smp-call-function-single patch). Does > > anyone know if this change is safe, or if there was a specific reason > > that topology_init() was left as an __initcall() on powerpc? > > In general, it's better to do initcalls as late as possible, so > __initcall() is preferred over subsys_initcall() if both work. Have you > tried doing it the other way and starting perfmon2 from a regular > __initcall()? For the moment, I made the change to topology_init() since it was the simplest fix to get things working. I have considered switching the perfmon2 initialization to __initcall(), but there are apparently some timing issues with ensuring that the perfmon2 core code is initialized before any of its sub-modules. Since they could all be compiled statically in the kernel, I'm not sure if there's a way to ensure the ordering of calls within a single initcall level. I'll need to ask Stephane if there were any other reasons why subsys_initcall() was used for perfmon2. Thanks, Arnd. -- Kevin Corry [EMAIL PROTECTED] http://www.ibm.com/linux/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Questions about porting perfmon2 to powerpc
Hello, Carl Love and I have been working on getting the latest perfmon2 patches (http://perfmon2.sourceforge.net/) working on Cell, and on powerpc in general. We've come up with some powerpc-specific questions and we're hoping to get some opinions from the powerpc kernel developers. First, the stock 2.6.20 kernel has a prototype in include/linux/smp.h for a function called smp_call_function_single(). However, this routine is only implemented on i386, x86_64, ia64, and mips. Perfmon2 apparently needs to call this to run a function on a specific CPU. Powerpc provides an smp_call_function() routine to run a function on all active CPUs, so I used that as a basis to add an smp_call_function_single() routine. I've included the patch below and was wondering if it looked like a sane approach. Next, we ran into a problem related to Perfmon2 initialization and sysfs. The problem turned out to be that the powerpc version of topology_init() is defined as an __initcall() routine, but Perfmon2's initialization is done as a subsys_initcall() routine. Thus, Perfmon2 tries to initialize its sysfs information before some of the powerpc cpu information has been initialized. However, on all other architectures, topology_init() is defined as a subsys_initcall() routine, so this problem was not seen on any other platforms. Changing the powerpc version of topology_init() to a subsys_initcall() seems to have fixed the bug. However, I'm not sure if that is going to cause problems elsewhere in the powerpc code. I've included the patch below (after the smp-call-function-single patch). Does anyone know if this change is safe, or if there was a specific reason that topology_init() was left as an __initcall() on powerpc? Thanks for your help! -- Kevin Corry [EMAIL PROTECTED] http://www.ibm.com/linux/ === Add an smp_call_function_single() to the powerpc architecture. This is mostly a copy of smp_call_function(), but with minor modifications to call only the specified CPU. Index: linux-2.6.20-perfmon/arch/powerpc/kernel/smp.c === --- linux-2.6.20-perfmon.orig/arch/powerpc/kernel/smp.c +++ linux-2.6.20-perfmon/arch/powerpc/kernel/smp.c @@ -287,6 +287,92 @@ int smp_call_function (void (*func) (voi EXPORT_SYMBOL(smp_call_function); +/* + * This function sends a 'generic call function' IPI to the specified CPU. + * + * [SUMMARY] Run a function on the specified CPUs. + * The function to run. This must be fast and non-blocking. + * An arbitrary pointer to pass to the function. + * currently unused. + * If true, wait (atomically) until function has completed on the + * other CPU. + * [RETURNS] 0 on success, else a negative status code. Does not return until + * remote CPU is nearly ready to execute <> or are or has executed. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler or from a bottom half handler. + */ +int smp_call_function_single(int cpuid, void (*func)(void *info), void *info, +int nonatomic, int wait) +{ + struct call_data_struct data; + int ret = -1, cpus = 1, me; + u64 timeout; + + /* Can deadlock when called with interrupts disabled */ + WARN_ON(irqs_disabled()); + + if (unlikely(smp_ops == NULL)) + return -1; + + me = get_cpu(); /* prevent preemption and reschedule on another processor */ + if (cpuid == me) { + printk(KERN_INFO "%s: trying to call self\n", __FUNCTION__); + put_cpu(); + return -EBUSY; + } + + data.func = func; + data.info = info; + atomic_set(&data.started, 0); + data.wait = wait; + if (wait) + atomic_set(&data.finished, 0); + + spin_lock(&call_lock); + + call_data = &data; + smp_wmb(); + /* Send a message to the specified CPU and wait for it to respond */ + smp_ops->message_pass(cpuid, PPC_MSG_CALL_FUNCTION); + + timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec; + + /* Wait for response */ + while (atomic_read(&data.started) != cpus) { + HMT_low(); + if (get_tb() >= timeout) { + printk("%s on cpu %d: cpu %d not responding\n", + __FUNCTION__, smp_processor_id(), cpuid); + debugger(NULL); + goto out; + } + } + + if (wait) { + while (atomic_read(&data.finished) != cpus) { + HMT_low(); + if (get_tb() >= timeout) { + printk("%s on cpu %d: cpu %d not finishing\n", + __FUNCTION__, smp
Re: device-mapper: fix TB stripe data corruption
On Friday 21 January 2005 3:20 pm, Roland Dreier wrote: > Kevin> We have to take a mod of the chunk value and the number of > Kevin> stripes (which can be a non-power-of-2, so a shift won't > Kevin> work). It's been my understanding that you couldn't mod a > Kevin> 64-bit value with a 32-bit value in the kernel. > > If I understand you correctly, do_div() (defined in ) > does what you need. Look at asm-generic/div64.h for a good > description of the precise semantics of do_div(). Thanks for the tip, Roland. That seems to be exactly what we needed. Here's a different version of Alasdair's patch that changes chunk to 64-bit and uses do_div(). -- Kevin Corry [EMAIL PROTECTED] http://evms.sourceforge.net/ In stripe_map(), change chunk to 64-bit and use do_div to divide and mod by the number of stripes. --- diff/drivers/md/dm-stripe.c 2005-01-21 15:55:02.093379864 -0600 +++ source/drivers/md/dm-stripe.c 2005-01-21 15:54:25.400957960 -0600 @@ -173,9 +173,8 @@ struct stripe_c *sc = (struct stripe_c *) ti->private; sector_t offset = bio->bi_sector - ti->begin; - uint32_t chunk = (uint32_t) (offset >> sc->chunk_shift); - uint32_t stripe = chunk % sc->stripes; /* 32bit modulus */ - chunk = chunk / sc->stripes; + sector_t chunk = offset >> sc->chunk_shift; + uint32_t stripe = do_div(chunk, sc->stripes); bio->bi_bdev = sc->stripe[stripe].dev->bdev; bio->bi_sector = sc->stripe[stripe].physical_start + @@ -210,7 +209,7 @@ static struct target_type stripe_target = { .name = "striped", - .version= {1, 0, 1}, + .version= {1, 0, 2}, .module = THIS_MODULE, .ctr= stripe_ctr, .dtr= stripe_dtr, - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: device-mapper: fix TB stripe data corruption
On Friday 21 January 2005 2:33 pm, Benjamin LaHaise wrote: > On Fri, Jan 21, 2005 at 06:12:03PM +, Alasdair G Kergon wrote: > > Missing cast thought to cause data corruption on devices with stripes > > > ~1TB. > > Why not make chunk a sector_t? We have to take a mod of the chunk value and the number of stripes (which can be a non-power-of-2, so a shift won't work). It's been my understanding that you couldn't mod a 64-bit value with a 32-bit value in the kernel. Just to be sure, I've changed "chunk" to a sector_t and recompiled, and get the following error: MODPOST *** Warning: "__udivdi3" [drivers/md/dm-mod.ko] undefined! *** Warning: "__umoddi3" [drivers/md/dm-mod.ko] undefined! -- Kevin Corry [EMAIL PROTECTED] http://evms.sourceforge.net/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/