Skip to contentSkip to conversation

Background memory scrubbing

DISCUSSION Robert Whitton 3 participants 3 messages Apr 20, 2011 – Apr 25, 2011

lore
Share & tools
lore
#0 lore raw
Quoted 12 lines · Rik van Riel
Quoted 10 lines · Robert Whitton

for each PFN from 256 to the highest valid PFN
{
if (pfn_valid(PFN))
{
page = pfn_to_page(PFN)
va = kmap(page)
atomic_scrub(va, PAGE_SIZE)
kunmap(page)
}

Quoted 4 lines
Quoted 2 lines

sleep(for_a_while)
}

What exactly does atomic_scrub do?

atomic_scrub is part of the edac subsystem see arch/x86/include/asm/edac.h. It simply does a locked add of zero to each DWORD in the specified range.

(a shame that for 64 bit platforms it doesn't use QWORDS but that's just an optimisation)

Quoted 24 lines
Quoted 2 lines

This code works absolutely fine up to a short distance beyond the 16MB

boundary (specifically it seems to always fail on my hardware at PFN 4105). At this point despite the fact that kmap returns a valid virtual address (and it is the virtual address that I expect - 0xffff880001009000) I get the kernel oops - "unable to handle kernel paging request".

Looks like you might be making some of the kernel code that is running at that moment unreachable, leading to a kernel page fault.

______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email [1]
______________________________________________________________________

Links:
------
[1]
http://webmail.eclipse.net.uk/parse.php?redirect=http://www.messagelabs.com
/email

#1 lore raw
Quoted 13 lines · Robert Whitton
Quoted 12 lines · Rik van Riel
Quoted 10 lines · Robert Whitton

for each PFN from 256 to the highest valid PFN
{
if (pfn_valid(PFN))
{
page = pfn_to_page(PFN)
va = kmap(page)
atomic_scrub(va, PAGE_SIZE)
kunmap(page)
}

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

sleep(for_a_while)
}

What exactly does atomic_scrub do?

atomic_scrub is part of the edac subsystem see arch/x86/include/asm/edac.h. It simply does a locked add of zero to each DWORD in the specified range.

I can think of only a few ways in which that could cause a kernel page fault.

One of the more obvious causes would be running into an area of kernel memory that is mapped read-only. Writing to a page that is mapped read-only would cause a page fault :)

Walking the page tables to check whether my guess is correct
should be possible in the current context. Look at current->mm->pgd for the page directory and start walking from there.

Incidentally, the kernel mappings should be the same for any process, so the above should hold true from any context.

#2 lore raw

Hi!

Quoted 17 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

for each PFN from 256 to the highest valid PFN
{
if (pfn_valid(PFN))
{
page = pfn_to_page(PFN)
va = kmap(page)
atomic_scrub(va, PAGE_SIZE)
kunmap(page)
}

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

sleep(for_a_while)
}

What exactly does atomic_scrub do?

atomic_scrub is part of the edac subsystem see arch/x86/include/asm/edac.h. It simply does a locked add of zero to each DWORD in the specified range.

Quoted 7 lines

I can think of only a few ways in which that could cause a kernel page fault.

One of the more obvious causes would be running into an area of kernel memory that is mapped read-only. Writing to a page that is mapped read-only would cause a page fault :)

...also... you are actually making kernel use "self modifying code" here. There are CPU bugs in that area... for example on K6.
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html