* [BUG][PPC32] Preemption patch for 2.4 Kernels
@ 2004-10-07 12:51 Gerhard Jaeger
0 siblings, 0 replies; only message in thread
From: Gerhard Jaeger @ 2004-10-07 12:51 UTC (permalink / raw)
To: Robert Love; +Cc: linux-kernel, linuxppc-devel
[-- Attachment #1: Type: text/plain, Size: 1774 bytes --]
Hi Robert,
maybe the 2.4 series is somewhat outdatet, but nevertheless used in
several embedded systems and also with your preemption patches.
During some investigations, we found out that the patches found on
http://www.kernel.org/pub/linux/kernel/people/rml/preempt-kernel/
contain a severe bug, when using the patches on PPC systems.
The affected function is get_pgd_fast() which is buried in
include/asm-ppc/pgalloc.h
While the original function looks like:
extern __inline__ pgd_t *get_pgd_fast(void)
{
unsigned long *ret;
if ((ret = pgd_quicklist) != NULL) {
pgd_quicklist = (unsigned long *)(*ret);
ret[0] = 0;
pgtable_cache_size--;
} else
ret = (unsigned long *)get_pgd_slow();
return (pgd_t *)ret;
}
the patched one is:
extern __inline__ pgd_t *get_pgd_fast(void)
{
unsigned long *ret;
preempt_disable();
if ((ret = pgd_quicklist) != NULL) {
pgd_quicklist = (unsigned long *)(*ret);
ret[0] = 0;
pgtable_cache_size--;
preempt_enable();
} else
preempt_enable();
ret = (unsigned long *)get_pgd_slow();
return (pgd_t *)ret;
}
And exactly the "else" path causes the problems ;) I guess it should be
} else {
preempt_enable();
ret = (unsigned long *)get_pgd_slow();
}
The attached patch will do it the right way, and you might want to correct
the patches on your web-space.
Best regards,
Gerhard Jaeger
--
Gerhard Jaeger <gjaeger@sysgo.com>
SYSGO AG Embedded and Real-Time Software
www.sysgo.com | www.elinos.com | www.osek.de | www.imerva.com
[-- Attachment #2: pgalloc.h.diff --]
[-- Type: text/x-diff, Size: 1474 bytes --]
--- pgalloc.h.orig 2003-11-28 19:26:21.000000000 +0100
+++ pgalloc.h 2004-10-07 14:41:28.000000000 +0200
@@ -72,20 +72,26 @@ extern __inline__ pgd_t *get_pgd_fast(vo
{
unsigned long *ret;
+ preempt_disable();
if ((ret = pgd_quicklist) != NULL) {
pgd_quicklist = (unsigned long *)(*ret);
ret[0] = 0;
pgtable_cache_size--;
- } else
+ preempt_enable();
+ } else {
+ preempt_enable();
ret = (unsigned long *)get_pgd_slow();
+ }
return (pgd_t *)ret;
}
extern __inline__ void free_pgd_fast(pgd_t *pgd)
{
+ preempt_disable();
*(unsigned long **)pgd = pgd_quicklist;
pgd_quicklist = (unsigned long *) pgd;
pgtable_cache_size++;
+ preempt_enable();
}
extern __inline__ void free_pgd_slow(pgd_t *pgd)
@@ -124,19 +130,23 @@ static inline pte_t *pte_alloc_one_fast(
{
unsigned long *ret;
+ preempt_disable();
if ((ret = pte_quicklist) != NULL) {
pte_quicklist = (unsigned long *)(*ret);
ret[0] = 0;
pgtable_cache_size--;
}
+ preempt_enable();
return (pte_t *)ret;
}
extern __inline__ void pte_free_fast(pte_t *pte)
{
+ preempt_disable();
*(unsigned long **)pte = pte_quicklist;
pte_quicklist = (unsigned long *) pte;
pgtable_cache_size++;
+ preempt_enable();
}
extern __inline__ void pte_free_slow(pte_t *pte)
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-10-07 12:55 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-07 12:51 [BUG][PPC32] Preemption patch for 2.4 Kernels Gerhard Jaeger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).