From: Andrew Morton <akpm@zip.com.au>
To: Jordan Breeding <jordan.breeding@attbi.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Problems with 2.5.23-mm1
Date: Thu, 29 Aug 2002 02:58:18 -0700 [thread overview]
Message-ID: <3D6DF03A.127DD087@zip.com.au> (raw)
In-Reply-To: 3D6DCEC1.7020102@attbi.com
Jordan Breeding wrote:
>
> Hello,
>
> I am trying to run 2.5.32-mm1. The first problem that I have is that
> if SMP, Preempt and Highmem are all turned on I get lots of problems at
> boot including a BUG in highmem.c, I can get the line number later if
> someone wants it (later tomorrow night). I then disabled highmem and
> got the system to boot. I have a few weird problems, one is that every
> once in a while I see the message "bad: schedule() with irqs disabled!"
> and then there is a code trace. I am attaching the decoded output of
> some of the traces. Another problem I am having is that I get this
> message on bootup: "mtrr: SMP support incomplete for this vendor". It
> seems that this would be a problem however the box works fine as far as
> I can tell. Thanks for any light anyone can shed on any of this and
> please let me know whether anyone needs to know more about this box or
> about the highmem line number to figure and of these problems out.
>
Well there are a couple of dopey bugs in swap.c which this patch fixes.
--- 2.5.32/mm/swap.c~preempt-fix Thu Aug 29 02:00:44 2002
+++ 2.5.32-akpm/mm/swap.c Thu Aug 29 02:06:21 2002
@@ -54,14 +54,14 @@ static struct pagevec lru_add_pvecs[NR_C
void lru_cache_add(struct page *page)
{
unsigned long flags;
- struct pagevec *pvec;
+ struct pagevec *pvec = &lru_add_pvecs[get_cpu()];
local_irq_save(flags);
- pvec = &lru_add_pvecs[smp_processor_id()];
page_cache_get(page);
if (!pagevec_add(pvec, page))
__pagevec_lru_add(pvec);
local_irq_restore(flags);
+ put_cpu();
}
void lru_add_drain(void)
@@ -210,6 +210,7 @@ void pagevec_deactivate_inactive(struct
void __pagevec_lru_add(struct pagevec *pvec)
{
int i;
+ unsigned long flags = 0;
struct zone *zone = NULL;
for (i = 0; i < pagevec_count(pvec); i++) {
@@ -218,16 +219,16 @@ void __pagevec_lru_add(struct pagevec *p
if (pagezone != zone) {
if (zone)
- spin_unlock_irq(&zone->lru_lock);
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
zone = pagezone;
- spin_lock_irq(&zone->lru_lock);
+ spin_lock_irqsave(&zone->lru_lock, flags);
}
if (TestSetPageLRU(page))
BUG();
add_page_to_inactive_list(zone, page);
}
if (zone)
- spin_unlock_irq(&zone->lru_lock);
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
pagevec_release(pvec);
}
But the slab.c one is trickier. The code is, basically:
local_irq_save(flags);
spin_lock(lock);
...
spin_unlock(lock);
and sure, if another CPU sets need_resched against this task and sends
a reschedule IPI then we can hit the spin_unlock() with need_resched
set, and this task will reschedule with interrupts off.
So there's a slab.c patch here which tries to fix that up too, but it's
really rather nasty, and it doesn't work, and I've had enough for the day.
There are other code paths in there which I missed, such the second
spin_unlock in __kmem_cache_alloc(). I think it would be cleaner
and saner to just use a local_irq_save_and_preempt_disable(flags)
throughout slab.
--- 2.5.32/mm/slab.c~preempt-fix Thu Aug 29 02:32:53 2002
+++ 2.5.32-akpm/mm/slab.c Thu Aug 29 02:51:03 2002
@@ -998,6 +998,7 @@ static void drain_cpu_caches(kmem_cache_
local_irq_disable();
free_block(cachep, cc_entry(ccold), ccold->avail);
local_irq_enable();
+ preempt_enable();
ccold->avail = 0;
}
smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
@@ -1610,11 +1611,14 @@ static inline void __free_block (kmem_ca
kmem_cache_free_one(cachep, *objpp);
}
+/*
+ * Returns with preemption disabled - caller must perform preempt_enable().
+ */
static void free_block (kmem_cache_t* cachep, void** objpp, int len)
{
spin_lock(&cachep->spinlock);
__free_block(cachep, objpp, len);
- spin_unlock(&cachep->spinlock);
+ _raw_spin_unlock(&cachep->spinlock);
}
#endif
@@ -1716,6 +1720,9 @@ void kmem_cache_free (kmem_cache_t *cach
local_irq_save(flags);
__kmem_cache_free(cachep, objp);
local_irq_restore(flags);
+#ifdef CONFIG_SMP
+ preempt_enable();
+#endif
}
/**
@@ -1737,6 +1744,9 @@ void kfree (const void *objp)
c = GET_PAGE_CACHE(virt_to_page(objp));
__kmem_cache_free(c, (void*)objp);
local_irq_restore(flags);
+#ifdef CONFIG_SMP
+ preempt_enable();
+#endif
}
unsigned int kmem_cache_size(kmem_cache_t *cachep)
@@ -1814,6 +1824,7 @@ static int kmem_tune_cpucache (kmem_cach
local_irq_disable();
free_block(cachep, cc_entry(ccold), ccold->avail);
local_irq_enable();
+ preempt_enable();
kfree(ccold);
}
return 0;
.
next prev parent reply other threads:[~2002-08-29 9:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-29 7:35 Problems with 2.5.23-mm1 Jordan Breeding
2002-08-29 9:58 ` Andrew Morton [this message]
2002-08-29 11:31 ` Dave Jones
2002-08-29 13:16 ` Jordan Breeding
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3D6DF03A.127DD087@zip.com.au \
--to=akpm@zip.com.au \
--cc=jordan.breeding@attbi.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox