Skip to contentSkip to conversation

pud_bad vs pud_bad

DISCUSSION Jeremy Fitzhardinge 4 participants 22 messages Feb 5, 2009 – Feb 6, 2009 Memory management

lore
Share & tools
lore
#0 lore raw

I'm looking at unifying the 32 and 64-bit versions of pud_bad.

32-bits defines it as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
}

and 64 as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}

I'm inclined to go with the 64-bit version, but I'm wondering if there's something subtle I'm missing here.

Thoughts?

J

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#1 lore raw
Quoted 11 lines · Jeremy Fitzhardinge

I'm looking at unifying the 32 and 64-bit versions of pud_bad.

32-bits defines it as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
}

and 64 as:

Quoted 8 lines

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}

I'm inclined to go with the 64-bit version, but I'm wondering if there's something subtle I'm missing here.

Why go with the 64-bit version? The 32-bit check looks more compact and should result in smaller code.

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw
Quoted 20 lines · Ingo Molnar
Quoted 17 lines · Jeremy Fitzhardinge

I'm looking at unifying the 32 and 64-bit versions of pud_bad.

32-bits defines it as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
}

and 64 as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}
Quoted 5 lines
Quoted 2 lines

I'm inclined to go with the 64-bit version, but I'm wondering if there's something subtle I'm missing here.

Why go with the 64-bit version? The 32-bit check looks more compact and should result in smaller code.

Well, its stricter. But I don't really understand what condition its actually testing for.

J

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
Quoted 25 lines · Jeremy Fitzhardinge
Quoted 24 lines · Ingo Molnar
Quoted 20 lines · Jeremy Fitzhardinge

I'm looking at unifying the 32 and 64-bit versions of pud_bad.

32-bits defines it as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
}

and 64 as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}

I'm inclined to go with the 64-bit version, but I'm wondering if there's something subtle I'm missing here.

Quoted 6 lines
Quoted 3 lines

Why go with the 64-bit version? The 32-bit check looks more compact and should result in smaller code.

Well, its stricter. But I don't really understand what condition its actually testing for.

Well it tests: "beyond the bits covered by PTE_PFN|_PAGE_USER, the rest must only be _KERNPG_TABLE".

The _KERNPG_TABLE bits are disjunct from PTE_PFN|_PAGE_USER bits, so this makes sense.

But the 32-bit check does the exact same thing but via a single binary
operation: it checks whether any bits outside of those bits are zero - just via a simpler test that compiles to more compact code.

So i'd go with the 32-bit version. (unless there are some sign-extension complications i'm missing - but i think we got rid of those already.)

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#4 lore raw
Quoted 3 lines · Ingo Molnar

But the 32-bit check does the exact same thing but via a single binary operation: it checks whether any bits outside of those bits are zero - just via a simpler test that compiles to more compact code.

So i'd go with the 32-bit version. (unless there are some sign-extension complications i'm missing - but i think we got rid of those already.)

OK, fair enough. I wouldn't be surprised if gcc does that transform anyway, but we may as well be consistent about it.

J

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#5 lore raw
Quoted 11 lines · Jeremy Fitzhardinge
Quoted 7 lines · Ingo Molnar

But the 32-bit check does the exact same thing but via a single binary
operation: it checks whether any bits outside of those bits are zero - just via a simpler test that compiles to more compact code.

So i'd go with the 32-bit version. (unless there are some sign-extension complications i'm missing - but i think we got rid of those already.)

OK, fair enough. I wouldn't be surprised if gcc does that transform anyway, but we may as well be consistent about it.

i checked and it doesnt - at least 4.3.2 inserts an extra AND instruction. So the 32-bit version is really better. (beyond being more readable)

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#6 lore raw
In reply to Ingo Molnar
Quoted 35 lines · Ingo Molnar
Quoted 24 lines · Jeremy Fitzhardinge
Quoted 23 lines · Ingo Molnar
Quoted 20 lines · Jeremy Fitzhardinge

I'm looking at unifying the 32 and 64-bit versions of pud_bad.

32-bits defines it as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
}

and 64 as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}

I'm inclined to go with the 64-bit version, but I'm wondering if there's something subtle I'm missing here.

Quoted 6 lines
Quoted 3 lines

Why go with the 64-bit version? The 32-bit check looks more compact and should result in smaller code.

Well, its stricter. But I don't really understand what condition its actually testing for.

Well it tests: "beyond the bits covered by PTE_PFN|_PAGE_USER, the rest must only be _KERNPG_TABLE".

Quoted 6 lines

The _KERNPG_TABLE bits are disjunct from PTE_PFN|_PAGE_USER bits, so this makes sense.

But the 32-bit check does the exact same thing but via a single binary
operation: it checks whether any bits outside of those bits are zero - just via a simpler test that compiles to more compact code.

Simpler and more compact, but not as strict: in particular, a value of 0 or 1 is identified as bad by that 64-bit test, but not by the 32-bit.

I most definitely prefer the stricter 64-bit version. I thought we'd gone around this all before, but maybe that was for pmd_bad(): there too one variant was weaker than the other and we went for the stronger.

However... I forget how the folding works out. The pgd in the 32-bit PAE case used to have just the pfn and the present bit set in that little array of four entries: if pud_bad() ends up getting applied to that, I guess it will blow up.

If so, my preferred answer would actually be to make those 4 entries look more like real ptes; but you may think I'm being a bit silly.

Not quite sure why wli is Cc'ed but I've fixed his address:
it's good to see you back, Bill.

Hugh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw
Quoted 39 lines · Hugh Dickins
Quoted 38 lines · Ingo Molnar
Quoted 24 lines · Jeremy Fitzhardinge
Quoted 23 lines · Ingo Molnar
Quoted 20 lines · Jeremy Fitzhardinge

I'm looking at unifying the 32 and 64-bit versions of pud_bad.

32-bits defines it as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
}

and 64 as:

static inline int pud_bad(pud_t pud)

{
	return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}

I'm inclined to go with the 64-bit version, but I'm wondering if there's something subtle I'm missing here.

Quoted 6 lines
Quoted 3 lines

Why go with the 64-bit version? The 32-bit check looks more compact and should result in smaller code.

Well, its stricter. But I don't really understand what condition its actually testing for.

Well it tests: "beyond the bits covered by PTE_PFN|_PAGE_USER, the rest must only be _KERNPG_TABLE".

The _KERNPG_TABLE bits are disjunct from PTE_PFN|_PAGE_USER bits, so this makes sense.

Quoted 6 lines
Quoted 3 lines

But the 32-bit check does the exact same thing but via a single binary
operation: it checks whether any bits outside of those bits are zero - just via a simpler test that compiles to more compact code.

Simpler and more compact, but not as strict: in particular, a value of 0 or 1 is identified as bad by that 64-bit test, but not by the 32-bit.

yes, indeed you are right - the 64-bit test does not allow the KERNPG_TABLE bits to go zero.

Those are the present, rw, accessed and dirty bits. Do they really matter that much? If a toplevel entry goes !present or readonly, we notice that _fast_, without any checks. If it goes !access or !dirty - does that matter?

These checks are done all the time, and even a single instruction can count. The bits that are checked are enough to notice random memory corruption.

( albeit these days with large RAM sizes pagetable corruption is quite rare
and only happens if it's specifically corrupting the pagetable - and then it's not just a single bit. Most of the memory corruption goes into the pagecache. )

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#8 lore raw
Quoted 2 lines · Hugh Dickins
Quoted 2 lines

Simpler and more compact, but not as strict: in particular, a value of 0 or 1 is identified as bad by that 64-bit test, but not by the 32-bit.

Quoted 11 lines · Ingo Molnar

yes, indeed you are right - the 64-bit test does not allow the KERNPG_TABLE bits to go zero.
Those are the present, rw, accessed and dirty bits. Do they really matter that much? If a toplevel entry goes !present or readonly, we notice that _fast_, without any checks. If it goes !access or !dirty - does that matter? These checks are done all the time, and even a single instruction can count. The bits that are checked are enough to notice random memory corruption. ( albeit these days with large RAM sizes pagetable corruption is quite rare
and only happens if it's specifically corrupting the pagetable - and then it's not just a single bit. Most of the memory corruption goes into the pagecache. )

The RW bit needs to be allowed to become read-only for hugetlb COW. Changing it over to the 32-bit method is a bugfix by that token.

-- wli

#9 lore raw
Quoted 3 lines · On Thu, 5 Feb 2009, [email protected] wrote:

The RW bit needs to be allowed to become read-only for hugetlb COW. Changing it over to the 32-bit method is a bugfix by that token.

If there's a bugfix to be made there, of course I'm in favour:
but how come we've never seen such a bug? hugetlb COW has been around for a year or two by now, hasn't it?

Hugh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#10 lore raw
Quoted 2 lines · On Thu, 5 Feb 2009, [email protected] wrote:
Quoted 2 lines

The RW bit needs to be allowed to become read-only for hugetlb COW. Changing it over to the 32-bit method is a bugfix by that token.

Quoted 3 lines · Hugh Dickins

If there's a bugfix to be made there, of course I'm in favour:
but how come we've never seen such a bug? hugetlb COW has been around for a year or two by now, hasn't it?

We can tell from the code that a write-protected pte mapping of a 1GB hugetlb page would be flagged as bad. It must not be called on ptes mapping hugetlb pages if they're not getting flagged.

-- wli

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#11 lore raw
Quoted 4 lines · On Thu, 5 Feb 2009, [email protected] wrote:
Quoted 2 lines · On Thu, 5 Feb 2009, [email protected] wrote:
Quoted 2 lines

The RW bit needs to be allowed to become read-only for hugetlb COW. Changing it over to the 32-bit method is a bugfix by that token.

Quoted 8 lines
Quoted 3 lines · Hugh Dickins

If there's a bugfix to be made there, of course I'm in favour:
but how come we've never seen such a bug? hugetlb COW has been around for a year or two by now, hasn't it?

We can tell from the code that a write-protected pte mapping of a 1GB hugetlb page would be flagged as bad. It must not be called on ptes mapping hugetlb pages if they're not getting flagged.

Ah, I see what you mean now. Yes, the hugetlb case goes its own way and doesn't normally hit those p??_bad() macro/inlines; but we got caught out in follow_page() a year ago, a bad looked huge or a huge looked bad, but I forget the details at this instant.

Hugh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#12 lore raw
In reply to Ingo Molnar
Quoted 11 lines · Ingo Molnar
Quoted 3 lines · Hugh Dickins

Simpler and more compact, but not as strict: in particular, a value of 0 or 1 is identified as bad by that 64-bit test, but not by the 32-bit.

yes, indeed you are right - the 64-bit test does not allow the KERNPG_TABLE bits to go zero.

Those are the present, rw, accessed and dirty bits. Do they really matter that much? If a toplevel entry goes !present or readonly, we notice that _fast_, without any checks. If it goes !access or !dirty - does that matter?

I've not given it a great deal of thought, why this or that bit. These p??_bad checks originate from 2.4 or earlier, and by mistake got weakened somewhere along the way, and last time it was discussed we agreed to strenghthen them (and IIRC Jeremy himself did so).

Quoted 3 lines

These checks are done all the time, and even a single instruction can count. The bits that are checked are enough to notice random memory corruption.

Well, I am surprised that you would be arguing for weakening such a very simple check.

Hugh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#13 lore raw
In reply to Hugh Dickins
Quoted 5 lines · Hugh Dickins

However... I forget how the folding works out. The pgd in the 32-bit PAE case used to have just the pfn and the present bit set in that little array of four entries: if pud_bad() ends up getting applied to that, I guess it will blow up.

Ah, that's a good point.

Quoted 3 lines

If so, my preferred answer would actually be to make those 4 entries look more like real ptes; but you may think I'm being a bit silly.

Hardware doesn't allow it. It will explode (well, trap) if you set anything other than P in the top level.

By the by, what are the chances we'll be able to deprecate non-PAE 32-bit?

J

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#14 lore raw
Quoted 6 lines · Jeremy Fitzhardinge
Quoted 4 lines · Hugh Dickins

However... I forget how the folding works out. The pgd in the 32-bit PAE case used to have just the pfn and the present bit set in that little array of four entries: if pud_bad() ends up getting applied to that, I guess it will blow up.

Quoted 7 lines

Ah, that's a good point.

Quoted 2 lines

If so, my preferred answer would actually be to make those 4 entries look more like real ptes; but you may think I'm being a bit silly.

Hardware doesn't allow it. It will explode (well, trap) if you set anything other than P in the top level.

Oh, interesting, I'd never realized that.

Quoted 1 line

By the by, what are the chances we'll be able to deprecate non-PAE 32-bit?

I sincerely hope 0! I shed no tears at losing support for NUMAQ, but why should we be forced to double all the 32-bit ptes? You want us all to be using NX? Or you just want to cut your test/edit matrix - that I can well understand!

Hugh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#15 lore raw
Quoted 6 lines · Hugh Dickins
Quoted 3 lines

Hardware doesn't allow it. It will explode (well, trap) if you set anything other than P in the top level.

Oh, interesting, I'd never realized that.

There are some later extensions to reuse some of the bits for things like tlb reload policy (I think; I'd have to check to be sure), so they're fairly non-pte-like.

Quoted 8 lines
Quoted 2 lines

By the by, what are the chances we'll be able to deprecate non-PAE 32-bit?

I sincerely hope 0! I shed no tears at losing support for NUMAQ, but why should we be forced to double all the 32-bit ptes? You want us all to be using NX? Or you just want to cut your test/edit matrix - that I can well understand!

Yes, that's the gist of it. We could simplify things by having only one pte format and only have to parameterise with 3/4 level pagetables. We'd lose support for non-PAE cpus, including the first Pentium M (which is probably still in fairly wide use, unfortunately).

J

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#16 lore raw
Quoted 9 lines · Jeremy Fitzhardinge
Quoted 4 lines

I sincerely hope 0! I shed no tears at losing support for NUMAQ, but why should we be forced to double all the 32-bit ptes? You want us all to be using NX? Or you just want to cut your test/edit matrix - that I can well understand!

Yes, that's the gist of it. We could simplify things by having only one pte format and only have to parameterise with 3/4 level pagetables. We'd lose support for non-PAE cpus, including the first Pentium M (which is probably still in fairly wide use, unfortunately).

We'd also lose a fair bit of performance (not to mention the pagetable footprint doubling that Hugh already mentioned) on 32-bit PAE capable systems that dont actually have RAM above 4G physical.

Bad idea really ...

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#17 lore raw
Quoted 2 lines · Ingo Molnar

We'd also lose a fair bit of performance (not to mention the pagetable footprint doubling that Hugh already mentioned) on 32-bit PAE capable systems that dont actually have RAM above 4G physical.

Why's that? Do you mean directly from using PAE, or as a side-effect of highmem?

J

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#18 lore raw
Quoted 7 lines · Jeremy Fitzhardinge
Quoted 3 lines · Ingo Molnar

We'd also lose a fair bit of performance (not to mention the pagetable footprint doubling that Hugh already mentioned) on 32-bit PAE capable systems that dont actually have RAM above 4G physical.

Why's that? Do you mean directly from using PAE, or as a side-effect of highmem?

just the act of using PAE was measured to cause multi-percent slowdown in fork() and exec() latencies, etc. The pagetables are twice as large so is that really surprising?

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#19 lore raw
Quoted 2 lines · Ingo Molnar

just the act of using PAE was measured to cause multi-percent slowdown in fork() and exec() latencies, etc. The pagetables are twice as large so is that really surprising?

Is there a similar slowdown running the CPU in 32 vs 64 bit mode? Or does having more/wider registers mitigate it?

J

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#20 lore raw
Quoted 8 lines · Jeremy Fitzhardinge
Quoted 4 lines · Ingo Molnar

just the act of using PAE was measured to cause multi-percent slowdown in fork() and exec() latencies, etc. The pagetables are twice as large so is that really surprising?

Is there a similar slowdown running the CPU in 32 vs 64 bit mode? Or does having more/wider registers mitigate it?

Yes, of course there's a slowdown on 64-bit kernels in fork() performance, mainly related to pte size.

Here's some numbers done with perfstat. The "fork" binary forks 256 times, waits for the child tasks and then exits. It is a 32-bit binary, statically linked - i.e. very similar layout and function on both 32-bit and 64-bit kernels.

The results (tabulated a bit, average result of 20 runs):

 $ perfstat -e -3,-4,-5 ./fork

Performance counter stats for './fork':

        32-bit  32-bit-PAE     64-bit
     ---------  ----------  ---------
     27.367537   30.660090  31.542003  task clock ticks     (msecs)

          5785        5810       5751  pagefaults           (events)
           389         388        388  context switches     (events)
             4           4          4  CPU migrations       (events)
     ---------  ----------  ---------
                    +12.0%     +15.2%  overhead

So PAE is 12.0% slower (the overhead of double the pte size and three page table levels), and 64-bit is 15.2% slower (the extra overhead of having four page table levels added to the overhead of double the pte size).

Larger ptes do not come for free and the 64-bit instructions do not mitigate the cachemiss overhead and memory bandwidth cost.

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#21 lore raw
In reply to Jeremy Fitzhardinge
Quoted 7 lines · Jeremy Fitzhardinge
Quoted 5 lines · Hugh Dickins

However... I forget how the folding works out. The pgd in the 32-bit PAE case used to have just the pfn and the present bit set in that little array of four entries: if pud_bad() ends up getting applied to that, I guess it will blow up.

Quoted 7 lines

Ah, that's a good point.

Quoted 2 lines

If so, my preferred answer would actually be to make those 4 entries look more like real ptes; but you may think I'm being a bit silly.

Hardware doesn't allow it. It will explode (well, trap) if you set anything other than P in the top level.

Yeah. I was the first Linux hacker in history to put a x86 CPU into PAE mode under Linux 10+ years ago, and i can attest to the 'explodes way too easily' aspect quite emphatically ;-) Took me 3-4 days to bootstrap it.

Quoted 1 line

By the by, what are the chances we'll be able to deprecate non-PAE 32-bit?

For the next 10 years: pretty much zero.

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>