* [GIT PULL] core kernel fixes
@ 2009-05-18 14:23 Ingo Molnar
2009-05-18 15:48 ` Linus Torvalds
2009-05-18 16:59 ` [GIT PULL, v2] " Ingo Molnar
0 siblings, 2 replies; 10+ messages in thread
From: Ingo Molnar @ 2009-05-18 14:23 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Andrew Morton, Thomas Gleixner, Peter Zijlstra
Linus,
Please pull the latest core-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus
Thanks,
Ingo
------------------>
Ingo Molnar (1):
lockdep: increase MAX_LOCKDEP_ENTRIES and MAX_LOCKDEP_CHAINS
Thomas Gleixner (1):
futex: futex mapping needs to be writable
kernel/futex.c | 2 +-
kernel/lockdep_internals.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/futex.c b/kernel/futex.c
index eef8cd2..09db3ae 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -235,7 +235,7 @@ static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
}
again:
- err = get_user_pages_fast(address, 1, 0, &page);
+ err = get_user_pages_fast(address, 1, 1, &page);
if (err < 0)
return err;
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
index a2cc7e9..699a2ac 100644
--- a/kernel/lockdep_internals.h
+++ b/kernel/lockdep_internals.h
@@ -54,9 +54,9 @@ enum {
* table (if it's not there yet), and we check it for lock order
* conflicts and deadlocks.
*/
-#define MAX_LOCKDEP_ENTRIES 8192UL
+#define MAX_LOCKDEP_ENTRIES 16384UL
-#define MAX_LOCKDEP_CHAINS_BITS 14
+#define MAX_LOCKDEP_CHAINS_BITS 15
#define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS)
#define MAX_LOCKDEP_CHAIN_HLOCKS (MAX_LOCKDEP_CHAINS*5)
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [GIT PULL] core kernel fixes
2009-05-18 14:23 [GIT PULL] core kernel fixes Ingo Molnar
@ 2009-05-18 15:48 ` Linus Torvalds
2009-05-18 19:20 ` Thomas Gleixner
2009-05-18 16:59 ` [GIT PULL, v2] " Ingo Molnar
1 sibling, 1 reply; 10+ messages in thread
From: Linus Torvalds @ 2009-05-18 15:48 UTC (permalink / raw)
To: Ingo Molnar; +Cc: linux-kernel, Andrew Morton, Thomas Gleixner, Peter Zijlstra
On Mon, 18 May 2009, Ingo Molnar wrote:
>
> Thomas Gleixner (1):
> futex: futex mapping needs to be writable
I do not believe this is right.
Just a few lines later, we have:
* NOTE: When userspace waits on a MAP_SHARED mapping, even if
* it's a read-only handle, it's expected that futexes attach to
* the object not the particular process.
note how we are _supposed_ to be able to wait for something that is
read-only. As such, asking for a writable page is bogus.
I'm not going to pull this. I can well imagine that there was a real bug,
but this is _not_ the real fix.
The commentary is also TOTAL CRAP as far as I can tell. It starts out
with:
commit 734b05b10e51d4ba38c8fc3ee02e846aab09eedf (futex: use
fast_gup()) calls get_user_pages_fast() with the write argument set to
0. This went unnoticed [...]
and that is pure and utter SHIT. The fact is, the write argument was
ALWAYS zero, and commit 734b05b10e51d4ba38c8fc3ee02e846aab09eedf has
nothing to do with anything what-so-ever, and nothing went unnoticed
anywhere.
The real bug was apparently just commit e4dc5b7a3 ("clean up").
I also have to object to the "Impact" line of that commit. That line is
nonsensical and stupid. I hate to bring up this discussion again, but
dammit, if those Impact lines are crap, then they are crap and should not
be there!
The fact that they _look_ nicer and do not break up the story any more
doesn't change that fact. If you cannot write sane and meaningful impact
lines, then f*ck me with a spoon - JUST DON'T DO THEM!
I'm upset. Quite frankly, there are just _so_ many things wrong with that
commit that I get angry when it is sent this late in the game.
Linus
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [GIT PULL] core kernel fixes
2009-05-18 15:48 ` Linus Torvalds
@ 2009-05-18 19:20 ` Thomas Gleixner
2009-05-19 20:52 ` Linus Torvalds
2009-05-19 22:20 ` Darren Hart
0 siblings, 2 replies; 10+ messages in thread
From: Thomas Gleixner @ 2009-05-18 19:20 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton, Peter Zijlstra
Linus,
On Mon, 18 May 2009, Linus Torvalds wrote:
> On Mon, 18 May 2009, Ingo Molnar wrote:
> >
> > Thomas Gleixner (1):
> > futex: futex mapping needs to be writable
>
> I do not believe this is right.
You are right to believe that :)
> Just a few lines later, we have:
>
> * NOTE: When userspace waits on a MAP_SHARED mapping, even if
> * it's a read-only handle, it's expected that futexes attach to
> * the object not the particular process.
>
> note how we are _supposed_ to be able to wait for something that is
> read-only. As such, asking for a writable page is bogus.
We write access the user space address in various places in the futex
functions, so we really need a writeable mapping for a bunch of the
futex ops.
We have an explicit check for the private futexes a few lines up.
if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
There are some of the futex ops which can be done with a RO mapping
though. I'm not sure if it makes much sense as user space (at least
glibc) always writes the variable and/or the surrounding members in
the user space data structures, but for now we should leave it RO for
the ones which do not modify the user value.
> I'm not going to pull this. I can well imagine that there was a real bug,
> but this is _not_ the real fix.
>
> The commentary is also TOTAL CRAP as far as I can tell. It starts out
> with:
>
> commit 734b05b10e51d4ba38c8fc3ee02e846aab09eedf (futex: use
> fast_gup()) calls get_user_pages_fast() with the write argument set to
> 0. This went unnoticed [...]
>
> and that is pure and utter SHIT. The fact is, the write argument was
> ALWAYS zero, and commit 734b05b10e51d4ba38c8fc3ee02e846aab09eedf has
> nothing to do with anything what-so-ever, and nothing went unnoticed
> anywhere.
Sorry, I misread the GUP commit.
> The real bug was apparently just commit e4dc5b7a3 ("clean up").
So we always had that write=0 mapping. And we did not notice that we
always faulted in the futex functions which modify the user space
variable simply because the fault was fixed up in the private futex
fault handling code. The removal of that code led to the problem which
we have right now.
Correct fix below.
Thanks,
tglx
------>
futex: setup writeable mapping for futex ops which modify user space data
The futex code installs a read only mapping via get_user_pages_fast()
even if the futex op function has to modify user space data. The
eventual fault was fixed up by futex_handle_fault() which walked the
VMA with mmap_sem held.
After the cleanup patches which removed the mmap_sem dependency of the
futex code commit 4dc5b7a36a49eff97050894cf1b3a9a02523717 (futex:
clean up fault logic) removed the private VMA walk logic from the
futex code. This change results in a stale RO mapping which is not
fixed up.
Instead of reintroducing the previous fault logic we set up the
mapping in get_user_pages_fast() read/write for all operations which
modify user space data. Also handle private futexes in the same way
and make the current unconditional access_ok(VERIFY_WRITE) depend on
the futex op.
Reported-by: Andreas Schwab <schwab@linux-m68k.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
CC: stable@kernel.org
diff --git a/kernel/futex.c b/kernel/futex.c
index eef8cd2..3d7519d 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -193,6 +193,7 @@ static void drop_futex_key_refs(union futex_key *key)
* @uaddr: virtual address of the futex
* @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED
* @key: address where result is stored.
+ * @rw: mapping needs to be read/write (values: VERIFY_READ, VERIFY_WRITE)
*
* Returns a negative error code or 0
* The key words are stored in *key on success.
@@ -203,7 +204,8 @@ static void drop_futex_key_refs(union futex_key *key)
*
* lock_page() might sleep, the caller should not hold a spinlock.
*/
-static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
+static int
+get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
{
unsigned long address = (unsigned long)uaddr;
struct mm_struct *mm = current->mm;
@@ -226,7 +228,7 @@ static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
* but access_ok() should be faster than find_vma()
*/
if (!fshared) {
- if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
+ if (unlikely(!access_ok(rw, uaddr, sizeof(u32))))
return -EFAULT;
key->private.mm = mm;
key->private.address = address;
@@ -235,7 +237,7 @@ static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
}
again:
- err = get_user_pages_fast(address, 1, 0, &page);
+ err = get_user_pages_fast(address, 1, rw == VERIFY_WRITE, &page);
if (err < 0)
return err;
@@ -677,7 +679,7 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset)
if (!bitset)
return -EINVAL;
- ret = get_futex_key(uaddr, fshared, &key);
+ ret = get_futex_key(uaddr, fshared, &key, VERIFY_READ);
if (unlikely(ret != 0))
goto out;
@@ -723,10 +725,10 @@ futex_wake_op(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
int ret, op_ret;
retry:
- ret = get_futex_key(uaddr1, fshared, &key1);
+ ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ);
if (unlikely(ret != 0))
goto out;
- ret = get_futex_key(uaddr2, fshared, &key2);
+ ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE);
if (unlikely(ret != 0))
goto out_put_key1;
@@ -814,10 +816,10 @@ static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
int ret, drop_count = 0;
retry:
- ret = get_futex_key(uaddr1, fshared, &key1);
+ ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ);
if (unlikely(ret != 0))
goto out;
- ret = get_futex_key(uaddr2, fshared, &key2);
+ ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_READ);
if (unlikely(ret != 0))
goto out_put_key1;
@@ -1140,7 +1142,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
q.bitset = bitset;
retry:
q.key = FUTEX_KEY_INIT;
- ret = get_futex_key(uaddr, fshared, &q.key);
+ ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_READ);
if (unlikely(ret != 0))
goto out;
@@ -1330,7 +1332,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
q.pi_state = NULL;
retry:
q.key = FUTEX_KEY_INIT;
- ret = get_futex_key(uaddr, fshared, &q.key);
+ ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_WRITE);
if (unlikely(ret != 0))
goto out;
@@ -1594,7 +1596,7 @@ retry:
if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current))
return -EPERM;
- ret = get_futex_key(uaddr, fshared, &key);
+ ret = get_futex_key(uaddr, fshared, &key, VERIFY_WRITE);
if (unlikely(ret != 0))
goto out;
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [GIT PULL] core kernel fixes
2009-05-18 19:20 ` Thomas Gleixner
@ 2009-05-19 20:52 ` Linus Torvalds
2009-05-19 21:45 ` Thomas Gleixner
2009-05-19 22:20 ` Darren Hart
1 sibling, 1 reply; 10+ messages in thread
From: Linus Torvalds @ 2009-05-19 20:52 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: Ingo Molnar, linux-kernel, Andrew Morton, Peter Zijlstra
On Mon, 18 May 2009, Thomas Gleixner wrote:
>
> So we always had that write=0 mapping. And we did not notice that we
> always faulted in the futex functions which modify the user space
> variable simply because the fault was fixed up in the private futex
> fault handling code. The removal of that code led to the problem which
> we have right now.
>
> Correct fix below.
Ok, this looks fine to me.
Should I take it like this, or pull from something?
Linus
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [GIT PULL] core kernel fixes
2009-05-18 19:20 ` Thomas Gleixner
2009-05-19 20:52 ` Linus Torvalds
@ 2009-05-19 22:20 ` Darren Hart
1 sibling, 0 replies; 10+ messages in thread
From: Darren Hart @ 2009-05-19 22:20 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Linus Torvalds, Ingo Molnar, linux-kernel, Andrew Morton, Peter Zijlstra
Thomas Gleixner wrote:
> Linus,
>
> On Mon, 18 May 2009, Linus Torvalds wrote:
>> On Mon, 18 May 2009, Ingo Molnar wrote:
>>> Thomas Gleixner (1):
>>> futex: futex mapping needs to be writable
>> I do not believe this is right.
>
> You are right to believe that :)
>
>> Just a few lines later, we have:
>>
>> * NOTE: When userspace waits on a MAP_SHARED mapping, even if
>> * it's a read-only handle, it's expected that futexes attach to
>> * the object not the particular process.
>>
>> note how we are _supposed_ to be able to wait for something that is
>> read-only. As such, asking for a writable page is bogus.
>
> We write access the user space address in various places in the futex
> functions, so we really need a writeable mapping for a bunch of the
> futex ops.
>
> We have an explicit check for the private futexes a few lines up.
>
> if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
>
> There are some of the futex ops which can be done with a RO mapping
> though. I'm not sure if it makes much sense as user space (at least
> glibc) always writes the variable and/or the surrounding members in
> the user space data structures, but for now we should leave it RO for
> the ones which do not modify the user value.
>
>> I'm not going to pull this. I can well imagine that there was a real bug,
>> but this is _not_ the real fix.
>>
>> The commentary is also TOTAL CRAP as far as I can tell. It starts out
>> with:
>>
>> commit 734b05b10e51d4ba38c8fc3ee02e846aab09eedf (futex: use
>> fast_gup()) calls get_user_pages_fast() with the write argument set to
>> 0. This went unnoticed [...]
>>
>> and that is pure and utter SHIT. The fact is, the write argument was
>> ALWAYS zero, and commit 734b05b10e51d4ba38c8fc3ee02e846aab09eedf has
>> nothing to do with anything what-so-ever, and nothing went unnoticed
>> anywhere.
>
> Sorry, I misread the GUP commit.
>
>> The real bug was apparently just commit e4dc5b7a3 ("clean up").
>
> So we always had that write=0 mapping. And we did not notice that we
> always faulted in the futex functions which modify the user space
> variable simply because the fault was fixed up in the private futex
> fault handling code. The removal of that code led to the problem which
> we have right now.
>
> Correct fix below.
>
> Thanks,
>
> tglx
> ------>
> futex: setup writeable mapping for futex ops which modify user space data
>
> The futex code installs a read only mapping via get_user_pages_fast()
> even if the futex op function has to modify user space data. The
> eventual fault was fixed up by futex_handle_fault() which walked the
> VMA with mmap_sem held.
>
> After the cleanup patches which removed the mmap_sem dependency of the
> futex code commit 4dc5b7a36a49eff97050894cf1b3a9a02523717 (futex:
> clean up fault logic) removed the private VMA walk logic from the
> futex code. This change results in a stale RO mapping which is not
> fixed up.
>
> Instead of reintroducing the previous fault logic we set up the
> mapping in get_user_pages_fast() read/write for all operations which
> modify user space data. Also handle private futexes in the same way
> and make the current unconditional access_ok(VERIFY_WRITE) depend on
> the futex op.
>
> Reported-by: Andreas Schwab <schwab@linux-m68k.org>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This looks to be an elegant fix to me and maintains the fault logic
cleanup that actually caused the stale RO mapping issue mentioned above.
My only comment would be that it further obsoletes some commentary in
functions like futex_lock_pi() about how fault handling is done. I'll
just add this to my list of futex commentary to fix!
Acked-by: Darren Hart <dvhltc@us.ibm.com>
> CC: stable@kernel.org
>
> diff --git a/kernel/futex.c b/kernel/futex.c
> index eef8cd2..3d7519d 100644
> --- a/kernel/futex.c
> +++ b/kernel/futex.c
> @@ -193,6 +193,7 @@ static void drop_futex_key_refs(union futex_key *key)
> * @uaddr: virtual address of the futex
> * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED
> * @key: address where result is stored.
> + * @rw: mapping needs to be read/write (values: VERIFY_READ, VERIFY_WRITE)
> *
> * Returns a negative error code or 0
> * The key words are stored in *key on success.
> @@ -203,7 +204,8 @@ static void drop_futex_key_refs(union futex_key *key)
> *
> * lock_page() might sleep, the caller should not hold a spinlock.
> */
> -static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
> +static int
> +get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
> {
> unsigned long address = (unsigned long)uaddr;
> struct mm_struct *mm = current->mm;
> @@ -226,7 +228,7 @@ static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
> * but access_ok() should be faster than find_vma()
> */
> if (!fshared) {
> - if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
> + if (unlikely(!access_ok(rw, uaddr, sizeof(u32))))
> return -EFAULT;
> key->private.mm = mm;
> key->private.address = address;
> @@ -235,7 +237,7 @@ static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key)
> }
>
> again:
> - err = get_user_pages_fast(address, 1, 0, &page);
> + err = get_user_pages_fast(address, 1, rw == VERIFY_WRITE, &page);
> if (err < 0)
> return err;
>
> @@ -677,7 +679,7 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset)
> if (!bitset)
> return -EINVAL;
>
> - ret = get_futex_key(uaddr, fshared, &key);
> + ret = get_futex_key(uaddr, fshared, &key, VERIFY_READ);
> if (unlikely(ret != 0))
> goto out;
>
> @@ -723,10 +725,10 @@ futex_wake_op(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
> int ret, op_ret;
>
> retry:
> - ret = get_futex_key(uaddr1, fshared, &key1);
> + ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ);
> if (unlikely(ret != 0))
> goto out;
> - ret = get_futex_key(uaddr2, fshared, &key2);
> + ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE);
> if (unlikely(ret != 0))
> goto out_put_key1;
>
> @@ -814,10 +816,10 @@ static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
> int ret, drop_count = 0;
>
> retry:
> - ret = get_futex_key(uaddr1, fshared, &key1);
> + ret = get_futex_key(uaddr1, fshared, &key1, VERIFY_READ);
> if (unlikely(ret != 0))
> goto out;
> - ret = get_futex_key(uaddr2, fshared, &key2);
> + ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_READ);
> if (unlikely(ret != 0))
> goto out_put_key1;
>
> @@ -1140,7 +1142,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
> q.bitset = bitset;
> retry:
> q.key = FUTEX_KEY_INIT;
> - ret = get_futex_key(uaddr, fshared, &q.key);
> + ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_READ);
> if (unlikely(ret != 0))
> goto out;
>
> @@ -1330,7 +1332,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
> q.pi_state = NULL;
> retry:
> q.key = FUTEX_KEY_INIT;
> - ret = get_futex_key(uaddr, fshared, &q.key);
> + ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_WRITE);
> if (unlikely(ret != 0))
> goto out;
>
> @@ -1594,7 +1596,7 @@ retry:
> if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current))
> return -EPERM;
>
> - ret = get_futex_key(uaddr, fshared, &key);
> + ret = get_futex_key(uaddr, fshared, &key, VERIFY_WRITE);
> if (unlikely(ret != 0))
> goto out;
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Darren Hart
IBM Linux Technology Center
Real-Time Linux Team
^ permalink raw reply [flat|nested] 10+ messages in thread
* [GIT PULL, v2] core kernel fixes
2009-05-18 14:23 [GIT PULL] core kernel fixes Ingo Molnar
2009-05-18 15:48 ` Linus Torvalds
@ 2009-05-18 16:59 ` Ingo Molnar
1 sibling, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2009-05-18 16:59 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Andrew Morton, Thomas Gleixner, Peter Zijlstra
Linus,
Please pull the latest core-fixes-for-linus-2 git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus-2
This excludes the "futex: futex mapping needs to be writable" commit
you objected to. Test-built and test-booted.
Thanks,
Ingo
------------------>
Ingo Molnar (1):
lockdep: increase MAX_LOCKDEP_ENTRIES and MAX_LOCKDEP_CHAINS
kernel/lockdep_internals.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
index a2cc7e9..699a2ac 100644
--- a/kernel/lockdep_internals.h
+++ b/kernel/lockdep_internals.h
@@ -54,9 +54,9 @@ enum {
* table (if it's not there yet), and we check it for lock order
* conflicts and deadlocks.
*/
-#define MAX_LOCKDEP_ENTRIES 8192UL
+#define MAX_LOCKDEP_ENTRIES 16384UL
-#define MAX_LOCKDEP_CHAINS_BITS 14
+#define MAX_LOCKDEP_CHAINS_BITS 15
#define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS)
#define MAX_LOCKDEP_CHAIN_HLOCKS (MAX_LOCKDEP_CHAINS*5)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [GIT PULL, v2] core kernel fixes
@ 2009-06-21 10:55 Ingo Molnar
0 siblings, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2009-06-21 10:55 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-kernel, Thomas Gleixner, Peter Zijlstra, Andrew Morton
Linus,
Please pull the latest core-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus
Left out the futex commit, it's being worked on.
Thanks,
Ingo
------------------>
Joerg Roedel (2):
dma-debug: check for sg_call_ents in best-fit algorithm too
dma-debug: be more careful when building reference entries
Peter Zijlstra (1):
lockdep: Select frame pointers on x86
lib/Kconfig.debug | 2 +-
lib/dma-debug.c | 149 +++++++++++++++++++++++++++++++++++------------------
2 files changed, 99 insertions(+), 52 deletions(-)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 6cdcf38..3be4b7c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -440,7 +440,7 @@ config LOCKDEP
bool
depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
select STACKTRACE
- select FRAME_POINTER if !X86 && !MIPS && !PPC && !ARM_UNWIND && !S390
+ select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390
select KALLSYMS
select KALLSYMS_ALL
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index ad65fc0..3b93129 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -262,11 +262,12 @@ static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket,
*/
matches += 1;
match_lvl = 0;
- entry->size == ref->size ? ++match_lvl : match_lvl;
- entry->type == ref->type ? ++match_lvl : match_lvl;
- entry->direction == ref->direction ? ++match_lvl : match_lvl;
+ entry->size == ref->size ? ++match_lvl : 0;
+ entry->type == ref->type ? ++match_lvl : 0;
+ entry->direction == ref->direction ? ++match_lvl : 0;
+ entry->sg_call_ents == ref->sg_call_ents ? ++match_lvl : 0;
- if (match_lvl == 3) {
+ if (match_lvl == 4) {
/* perfect-fit - return the result */
return entry;
} else if (match_lvl > last_lvl) {
@@ -873,72 +874,68 @@ static void check_for_illegal_area(struct device *dev, void *addr, u64 size)
"[addr=%p] [size=%llu]\n", addr, size);
}
-static void check_sync(struct device *dev, dma_addr_t addr,
- u64 size, u64 offset, int direction, bool to_cpu)
+static void check_sync(struct device *dev,
+ struct dma_debug_entry *ref,
+ bool to_cpu)
{
- struct dma_debug_entry ref = {
- .dev = dev,
- .dev_addr = addr,
- .size = size,
- .direction = direction,
- };
struct dma_debug_entry *entry;
struct hash_bucket *bucket;
unsigned long flags;
- bucket = get_hash_bucket(&ref, &flags);
+ bucket = get_hash_bucket(ref, &flags);
- entry = hash_bucket_find(bucket, &ref);
+ entry = hash_bucket_find(bucket, ref);
if (!entry) {
err_printk(dev, NULL, "DMA-API: device driver tries "
"to sync DMA memory it has not allocated "
"[device address=0x%016llx] [size=%llu bytes]\n",
- (unsigned long long)addr, size);
+ (unsigned long long)ref->dev_addr, ref->size);
goto out;
}
- if ((offset + size) > entry->size) {
+ if (ref->size > entry->size) {
err_printk(dev, entry, "DMA-API: device driver syncs"
" DMA memory outside allocated range "
"[device address=0x%016llx] "
- "[allocation size=%llu bytes] [sync offset=%llu] "
- "[sync size=%llu]\n", entry->dev_addr, entry->size,
- offset, size);
+ "[allocation size=%llu bytes] "
+ "[sync offset+size=%llu]\n",
+ entry->dev_addr, entry->size,
+ ref->size);
}
- if (direction != entry->direction) {
+ if (ref->direction != entry->direction) {
err_printk(dev, entry, "DMA-API: device driver syncs "
"DMA memory with different direction "
"[device address=0x%016llx] [size=%llu bytes] "
"[mapped with %s] [synced with %s]\n",
- (unsigned long long)addr, entry->size,
+ (unsigned long long)ref->dev_addr, entry->size,
dir2name[entry->direction],
- dir2name[direction]);
+ dir2name[ref->direction]);
}
if (entry->direction == DMA_BIDIRECTIONAL)
goto out;
if (to_cpu && !(entry->direction == DMA_FROM_DEVICE) &&
- !(direction == DMA_TO_DEVICE))
+ !(ref->direction == DMA_TO_DEVICE))
err_printk(dev, entry, "DMA-API: device driver syncs "
"device read-only DMA memory for cpu "
"[device address=0x%016llx] [size=%llu bytes] "
"[mapped with %s] [synced with %s]\n",
- (unsigned long long)addr, entry->size,
+ (unsigned long long)ref->dev_addr, entry->size,
dir2name[entry->direction],
- dir2name[direction]);
+ dir2name[ref->direction]);
if (!to_cpu && !(entry->direction == DMA_TO_DEVICE) &&
- !(direction == DMA_FROM_DEVICE))
+ !(ref->direction == DMA_FROM_DEVICE))
err_printk(dev, entry, "DMA-API: device driver syncs "
"device write-only DMA memory to device "
"[device address=0x%016llx] [size=%llu bytes] "
"[mapped with %s] [synced with %s]\n",
- (unsigned long long)addr, entry->size,
+ (unsigned long long)ref->dev_addr, entry->size,
dir2name[entry->direction],
- dir2name[direction]);
+ dir2name[ref->direction]);
out:
put_hash_bucket(bucket, &flags);
@@ -1036,19 +1033,16 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
}
EXPORT_SYMBOL(debug_dma_map_sg);
-static int get_nr_mapped_entries(struct device *dev, struct scatterlist *s)
+static int get_nr_mapped_entries(struct device *dev,
+ struct dma_debug_entry *ref)
{
- struct dma_debug_entry *entry, ref;
+ struct dma_debug_entry *entry;
struct hash_bucket *bucket;
unsigned long flags;
int mapped_ents;
- ref.dev = dev;
- ref.dev_addr = sg_dma_address(s);
- ref.size = sg_dma_len(s),
-
- bucket = get_hash_bucket(&ref, &flags);
- entry = hash_bucket_find(bucket, &ref);
+ bucket = get_hash_bucket(ref, &flags);
+ entry = hash_bucket_find(bucket, ref);
mapped_ents = 0;
if (entry)
@@ -1076,16 +1070,14 @@ void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
.dev_addr = sg_dma_address(s),
.size = sg_dma_len(s),
.direction = dir,
- .sg_call_ents = 0,
+ .sg_call_ents = nelems,
};
if (mapped_ents && i >= mapped_ents)
break;
- if (!i) {
- ref.sg_call_ents = nelems;
- mapped_ents = get_nr_mapped_entries(dev, s);
- }
+ if (!i)
+ mapped_ents = get_nr_mapped_entries(dev, &ref);
check_unmap(&ref);
}
@@ -1140,10 +1132,19 @@ EXPORT_SYMBOL(debug_dma_free_coherent);
void debug_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
size_t size, int direction)
{
+ struct dma_debug_entry ref;
+
if (unlikely(global_disable))
return;
- check_sync(dev, dma_handle, size, 0, direction, true);
+ ref.type = dma_debug_single;
+ ref.dev = dev;
+ ref.dev_addr = dma_handle;
+ ref.size = size;
+ ref.direction = direction;
+ ref.sg_call_ents = 0;
+
+ check_sync(dev, &ref, true);
}
EXPORT_SYMBOL(debug_dma_sync_single_for_cpu);
@@ -1151,10 +1152,19 @@ void debug_dma_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
int direction)
{
+ struct dma_debug_entry ref;
+
if (unlikely(global_disable))
return;
- check_sync(dev, dma_handle, size, 0, direction, false);
+ ref.type = dma_debug_single;
+ ref.dev = dev;
+ ref.dev_addr = dma_handle;
+ ref.size = size;
+ ref.direction = direction;
+ ref.sg_call_ents = 0;
+
+ check_sync(dev, &ref, false);
}
EXPORT_SYMBOL(debug_dma_sync_single_for_device);
@@ -1163,10 +1173,19 @@ void debug_dma_sync_single_range_for_cpu(struct device *dev,
unsigned long offset, size_t size,
int direction)
{
+ struct dma_debug_entry ref;
+
if (unlikely(global_disable))
return;
- check_sync(dev, dma_handle, size, offset, direction, true);
+ ref.type = dma_debug_single;
+ ref.dev = dev;
+ ref.dev_addr = dma_handle;
+ ref.size = offset + size;
+ ref.direction = direction;
+ ref.sg_call_ents = 0;
+
+ check_sync(dev, &ref, true);
}
EXPORT_SYMBOL(debug_dma_sync_single_range_for_cpu);
@@ -1175,10 +1194,19 @@ void debug_dma_sync_single_range_for_device(struct device *dev,
unsigned long offset,
size_t size, int direction)
{
+ struct dma_debug_entry ref;
+
if (unlikely(global_disable))
return;
- check_sync(dev, dma_handle, size, offset, direction, false);
+ ref.type = dma_debug_single;
+ ref.dev = dev;
+ ref.dev_addr = dma_handle;
+ ref.size = offset + size;
+ ref.direction = direction;
+ ref.sg_call_ents = 0;
+
+ check_sync(dev, &ref, false);
}
EXPORT_SYMBOL(debug_dma_sync_single_range_for_device);
@@ -1192,14 +1220,24 @@ void debug_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
return;
for_each_sg(sg, s, nelems, i) {
+
+ struct dma_debug_entry ref = {
+ .type = dma_debug_sg,
+ .dev = dev,
+ .paddr = sg_phys(s),
+ .dev_addr = sg_dma_address(s),
+ .size = sg_dma_len(s),
+ .direction = direction,
+ .sg_call_ents = nelems,
+ };
+
if (!i)
- mapped_ents = get_nr_mapped_entries(dev, s);
+ mapped_ents = get_nr_mapped_entries(dev, &ref);
if (i >= mapped_ents)
break;
- check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
- direction, true);
+ check_sync(dev, &ref, true);
}
}
EXPORT_SYMBOL(debug_dma_sync_sg_for_cpu);
@@ -1214,14 +1252,23 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
return;
for_each_sg(sg, s, nelems, i) {
+
+ struct dma_debug_entry ref = {
+ .type = dma_debug_sg,
+ .dev = dev,
+ .paddr = sg_phys(s),
+ .dev_addr = sg_dma_address(s),
+ .size = sg_dma_len(s),
+ .direction = direction,
+ .sg_call_ents = nelems,
+ };
if (!i)
- mapped_ents = get_nr_mapped_entries(dev, s);
+ mapped_ents = get_nr_mapped_entries(dev, &ref);
if (i >= mapped_ents)
break;
- check_sync(dev, sg_dma_address(s), sg_dma_len(s), 0,
- direction, false);
+ check_sync(dev, &ref, false);
}
}
EXPORT_SYMBOL(debug_dma_sync_sg_for_device);
^ permalink raw reply [flat|nested] 10+ messages in thread* [GIT PULL] core kernel fixes
@ 2009-07-10 16:28 Ingo Molnar
2009-07-10 19:06 ` Linus Torvalds
0 siblings, 1 reply; 10+ messages in thread
From: Ingo Molnar @ 2009-07-10 16:28 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, Thomas Gleixner, Peter Zijlstra
Linus,
Please pull the latest core-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus
Thanks,
Ingo
------------------>
Arnd Bergmann (1):
signals: declare sys_rt_tgsigqueueinfo in syscalls.h
Ingo Molnar (1):
dma-debug: Put all hash-chain locks into the same lock class
Joerg Roedel (1):
dma-debug: fix off-by-one error in overlap function
Maynard Johnson (1):
oprofile: reset bt_lost_no_mapping with other stats
Paul E. McKenney (1):
rcu: Mark Hierarchical RCU no longer experimental
Robert Richter (1):
x86/oprofile: rename kernel parameter for architectural perfmon to arch_perfmon
Documentation/kernel-parameters.txt | 4 ++--
arch/x86/oprofile/nmi_int.c | 2 +-
drivers/oprofile/oprofile_stats.c | 1 +
include/linux/syscalls.h | 2 ++
kernel/rcutree.c | 3 +--
lib/dma-debug.c | 4 ++--
6 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 92e1ab8..c59e965 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1728,8 +1728,8 @@ and is between 256 and 4096 characters. It is defined in the file
oprofile.cpu_type= Force an oprofile cpu type
This might be useful if you have an older oprofile
userland or if you want common events.
- Format: { archperfmon }
- archperfmon: [X86] Force use of architectural
+ Format: { arch_perfmon }
+ arch_perfmon: [X86] Force use of architectural
perfmon on Intel CPUs instead of the
CPU specific event set.
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index b07dd8d..89b9a5c 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -390,7 +390,7 @@ static int __init p4_init(char **cpu_type)
static int force_arch_perfmon;
static int force_cpu_type(const char *str, struct kernel_param *kp)
{
- if (!strcmp(str, "archperfmon")) {
+ if (!strcmp(str, "arch_perfmon")) {
force_arch_perfmon = 1;
printk(KERN_INFO "oprofile: forcing architectural perfmon\n");
}
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
index e1f6ce0..3c2270a 100644
--- a/drivers/oprofile/oprofile_stats.c
+++ b/drivers/oprofile/oprofile_stats.c
@@ -33,6 +33,7 @@ void oprofile_reset_stats(void)
atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
atomic_set(&oprofile_stats.event_lost_overflow, 0);
+ atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
}
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index fa4242c..80de700 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -321,6 +321,8 @@ asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese,
siginfo_t __user *uinfo,
const struct timespec __user *uts,
size_t sigsetsize);
+asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
+ siginfo_t __user *uinfo);
asmlinkage long sys_kill(int pid, int sig);
asmlinkage long sys_tgkill(int tgid, int pid, int sig);
asmlinkage long sys_tkill(int pid, int sig);
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 0dccfbb..7717b95 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1533,7 +1533,7 @@ void __init __rcu_init(void)
int j;
struct rcu_node *rnp;
- printk(KERN_WARNING "Experimental hierarchical RCU implementation.\n");
+ printk(KERN_INFO "Hierarchical RCU implementation.\n");
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
@@ -1546,7 +1546,6 @@ void __init __rcu_init(void)
rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long)i);
/* Register notifier for non-boot CPUs */
register_cpu_notifier(&rcu_nb);
- printk(KERN_WARNING "Experimental hierarchical RCU init done.\n");
}
module_param(blimit, int, 0);
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 3b93129..c9187fe 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -716,7 +716,7 @@ void dma_debug_init(u32 num_entries)
for (i = 0; i < HASH_SIZE; ++i) {
INIT_LIST_HEAD(&dma_entry_hash[i].list);
- dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&dma_entry_hash[i].lock);
}
if (dma_debug_fs_init() != 0) {
@@ -862,7 +862,7 @@ static inline bool overlap(void *addr, u64 size, void *start, void *end)
return ((addr >= start && addr < end) ||
(addr2 >= start && addr2 < end) ||
- ((addr < start) && (addr2 >= end)));
+ ((addr < start) && (addr2 > end)));
}
static void check_for_illegal_area(struct device *dev, void *addr, u64 size)
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [GIT PULL] core kernel fixes
2009-07-10 16:28 [GIT PULL] " Ingo Molnar
@ 2009-07-10 19:06 ` Linus Torvalds
2009-07-10 19:31 ` Ingo Molnar
0 siblings, 1 reply; 10+ messages in thread
From: Linus Torvalds @ 2009-07-10 19:06 UTC (permalink / raw)
To: Ingo Molnar
Cc: Linux Kernel Mailing List, Thomas Gleixner, Peter Zijlstra, Joerg Roedel
On Fri, 10 Jul 2009, Ingo Molnar wrote:
>
> Joerg Roedel (1):
> dma-debug: fix off-by-one error in overlap function
>
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> index 3b93129..c9187fe 100644
> --- a/lib/dma-debug.c
> +++ b/lib/dma-debug.c
> @@ -862,7 +862,7 @@ static inline bool overlap(void *addr, u64 size, void *start, void *end)
>
> return ((addr >= start && addr < end) ||
> (addr2 >= start && addr2 < end) ||
> - ((addr < start) && (addr2 >= end)));
> + ((addr < start) && (addr2 > end)));
> }
>
> static void check_for_illegal_area(struct device *dev, void *addr, u64 size)
The above seems like total shit.
If (addr < start && addr2 == end) then the two areas very much overlap.
What am I missing (apart from the fact that all those variables are
horribly badly named)?
Also, the tests make no sense. That's not how you are supposed to check
for overlap to begin with.
Isn't it easier to test for _not_ overlapping?
/* range1 is fully before range2 */
(end1 <= start2 ||
/* range1 is fully after range2 */
start1 >= end2)
possibly together with checking for overflow in the size addition? But I
didn't think that through, so maybe I'm doing something stupid.
Finally, why is 'size' a u64? It will overflow anyway if it's bigger than
a pointer, so it should be just 'unsigned long'. Or it should all be done
in u64 if people care. Or we should care about overflow (which cannot be
done with pointers).
Also, comparing pointers is unsafe to begin with. It's not clear if they
are signed or unsigned comparisons, and gcc has historically had bugs here
(only unsigned comparisons make sense for pointers, but _technically_ a
crazy compiler person could argue that at least in some environments any
valid pointers to the same object - which is the only thing C defines -
must not cross the sign barrier, so they use a buggy signed compare).
IOW, I think this whole function is just total crap, apparently put
together by randomly assembling characters until it compiles. Somebody
should put more effort into looking at it, but I think it should be
something like
static inline int overlap(void *addr, unsigned long len, void *start, void *end)
{
unsigned long a1 = (unsigned long) addr;
unsigned long b1 = a1 + len;
unsigned long a2 = (unsigned long) start;
unsigned long b2 = (unsigned long) end;
#ifdef WE_CARE_DEEPLY
/* Overflow? */
if (b1 < a1)
return 1;
#ifdef AND_ARE_ANAL
if (b2 < a2)
return 1;
#endif
#endif
return !(b1 <= a2 || a1 >= b2);
}
but I really migth have done soemthing wrong there. It's a simple
function, but somebody needs to double-check that I haven't made it worse.
Linus
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [GIT PULL] core kernel fixes
2009-07-10 19:06 ` Linus Torvalds
@ 2009-07-10 19:31 ` Ingo Molnar
2009-07-10 20:36 ` [GIT PULL, v2] " Ingo Molnar
0 siblings, 1 reply; 10+ messages in thread
From: Ingo Molnar @ 2009-07-10 19:31 UTC (permalink / raw)
To: Linus Torvalds
Cc: Linux Kernel Mailing List, Thomas Gleixner, Peter Zijlstra, Joerg Roedel
* Linus Torvalds <torvalds@linux-foundation.org> wrote:
>
> On Fri, 10 Jul 2009, Ingo Molnar wrote:
> >
> > Joerg Roedel (1):
> > dma-debug: fix off-by-one error in overlap function
> >
> > diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> > index 3b93129..c9187fe 100644
> > --- a/lib/dma-debug.c
> > +++ b/lib/dma-debug.c
> > @@ -862,7 +862,7 @@ static inline bool overlap(void *addr, u64 size, void *start, void *end)
> >
> > return ((addr >= start && addr < end) ||
> > (addr2 >= start && addr2 < end) ||
> > - ((addr < start) && (addr2 >= end)));
> > + ((addr < start) && (addr2 > end)));
> > }
> >
> > static void check_for_illegal_area(struct device *dev, void *addr, u64 size)
>
> The above seems like total shit.
>
> If (addr < start && addr2 == end) then the two areas very much overlap.
>
> What am I missing (apart from the fact that all those variables are
> horribly badly named)?
>
> Also, the tests make no sense. That's not how you are supposed to check
> for overlap to begin with.
>
> Isn't it easier to test for _not_ overlapping?
>
> /* range1 is fully before range2 */
> (end1 <= start2 ||
> /* range1 is fully after range2 */
> start1 >= end2)
>
> possibly together with checking for overflow in the size addition?
> But I didn't think that through, so maybe I'm doing something
> stupid.
>
> Finally, why is 'size' a u64? It will overflow anyway if it's
> bigger than a pointer, so it should be just 'unsigned long'. Or it
> should all be done in u64 if people care. Or we should care about
> overflow (which cannot be done with pointers).
>
> Also, comparing pointers is unsafe to begin with. It's not clear
> if they are signed or unsigned comparisons, and gcc has
> historically had bugs here (only unsigned comparisons make sense
> for pointers, but _technically_ a crazy compiler person could
> argue that at least in some environments any valid pointers to the
> same object - which is the only thing C defines - must not cross
> the sign barrier, so they use a buggy signed compare).
hm, indeed - and i missed that.
[ Even in the pointer space i think this cast is slightly confused
too:
static inline bool overlap(void *addr, u64 size, void *start, void *end)
{
void *addr2 = (char *)addr + size;
as void * has byte granular arithmetics already so 'addr + size'
would suffice. ]
> IOW, I think this whole function is just total crap, apparently
> put together by randomly assembling characters until it compiles.
> Somebody should put more effort into looking at it, but I think it
> should be something like
>
> static inline int overlap(void *addr, unsigned long len, void *start, void *end)
> {
> unsigned long a1 = (unsigned long) addr;
> unsigned long b1 = a1 + len;
> unsigned long a2 = (unsigned long) start;
> unsigned long b2 = (unsigned long) end;
At least some arguments have unsigned long natural types (they come
out of page_address() for example) so the function parameters could
perhaps be changed to unsigned long too as well.
> #ifdef WE_CARE_DEEPLY
> /* Overflow? */
> if (b1 < a1)
> return 1;
> #ifdef AND_ARE_ANAL
> if (b2 < a2)
> return 1;
> #endif
> #endif
> return !(b1 <= a2 || a1 >= b2);
> }
>
> but I really migth have done soemthing wrong there. It's a simple
> function, but somebody needs to double-check that I haven't made
> it worse.
Looks correct to me.
Ingo
^ permalink raw reply [flat|nested] 10+ messages in thread* [GIT PULL, v2] core kernel fixes
2009-07-10 19:31 ` Ingo Molnar
@ 2009-07-10 20:36 ` Ingo Molnar
0 siblings, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2009-07-10 20:36 UTC (permalink / raw)
To: Linus Torvalds
Cc: Linux Kernel Mailing List, Thomas Gleixner, Peter Zijlstra, Joerg Roedel
Linus,
Please pull the v2 core-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus-2
This has the overlap() bug(s) fixed. [ You might want to hold off on
pulling this for a few hours, just in case the fresh dma-debug.c fix
has any unexpected (and unprecedented) breakages. ]
Thanks,
Ingo
------------------>
Arnd Bergmann (1):
signals: declare sys_rt_tgsigqueueinfo in syscalls.h
Ingo Molnar (2):
dma-debug: Put all hash-chain locks into the same lock class
dma-debug: Fix the overlap() function to be correct and readable
Joerg Roedel (1):
dma-debug: fix off-by-one error in overlap function
Maynard Johnson (1):
oprofile: reset bt_lost_no_mapping with other stats
Paul E. McKenney (1):
rcu: Mark Hierarchical RCU no longer experimental
Robert Richter (1):
x86/oprofile: rename kernel parameter for architectural perfmon to arch_perfmon
Documentation/kernel-parameters.txt | 4 ++--
arch/x86/oprofile/nmi_int.c | 2 +-
drivers/oprofile/oprofile_stats.c | 1 +
include/linux/syscalls.h | 2 ++
kernel/rcutree.c | 3 +--
lib/dma-debug.c | 26 +++++++++++++-------------
6 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 92e1ab8..c59e965 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1728,8 +1728,8 @@ and is between 256 and 4096 characters. It is defined in the file
oprofile.cpu_type= Force an oprofile cpu type
This might be useful if you have an older oprofile
userland or if you want common events.
- Format: { archperfmon }
- archperfmon: [X86] Force use of architectural
+ Format: { arch_perfmon }
+ arch_perfmon: [X86] Force use of architectural
perfmon on Intel CPUs instead of the
CPU specific event set.
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index b07dd8d..89b9a5c 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -390,7 +390,7 @@ static int __init p4_init(char **cpu_type)
static int force_arch_perfmon;
static int force_cpu_type(const char *str, struct kernel_param *kp)
{
- if (!strcmp(str, "archperfmon")) {
+ if (!strcmp(str, "arch_perfmon")) {
force_arch_perfmon = 1;
printk(KERN_INFO "oprofile: forcing architectural perfmon\n");
}
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
index e1f6ce0..3c2270a 100644
--- a/drivers/oprofile/oprofile_stats.c
+++ b/drivers/oprofile/oprofile_stats.c
@@ -33,6 +33,7 @@ void oprofile_reset_stats(void)
atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
atomic_set(&oprofile_stats.event_lost_overflow, 0);
+ atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
}
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index fa4242c..80de700 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -321,6 +321,8 @@ asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese,
siginfo_t __user *uinfo,
const struct timespec __user *uts,
size_t sigsetsize);
+asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
+ siginfo_t __user *uinfo);
asmlinkage long sys_kill(int pid, int sig);
asmlinkage long sys_tgkill(int tgid, int pid, int sig);
asmlinkage long sys_tkill(int pid, int sig);
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 0dccfbb..7717b95 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1533,7 +1533,7 @@ void __init __rcu_init(void)
int j;
struct rcu_node *rnp;
- printk(KERN_WARNING "Experimental hierarchical RCU implementation.\n");
+ printk(KERN_INFO "Hierarchical RCU implementation.\n");
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
@@ -1546,7 +1546,6 @@ void __init __rcu_init(void)
rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long)i);
/* Register notifier for non-boot CPUs */
register_cpu_notifier(&rcu_nb);
- printk(KERN_WARNING "Experimental hierarchical RCU init done.\n");
}
module_param(blimit, int, 0);
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 3b93129..65b0d99 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -716,7 +716,7 @@ void dma_debug_init(u32 num_entries)
for (i = 0; i < HASH_SIZE; ++i) {
INIT_LIST_HEAD(&dma_entry_hash[i].list);
- dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&dma_entry_hash[i].lock);
}
if (dma_debug_fs_init() != 0) {
@@ -856,22 +856,21 @@ static void check_for_stack(struct device *dev, void *addr)
"stack [addr=%p]\n", addr);
}
-static inline bool overlap(void *addr, u64 size, void *start, void *end)
+static inline bool overlap(void *addr, unsigned long len, void *start, void *end)
{
- void *addr2 = (char *)addr + size;
+ unsigned long a1 = (unsigned long)addr;
+ unsigned long b1 = a1 + len;
+ unsigned long a2 = (unsigned long)start;
+ unsigned long b2 = (unsigned long)end;
- return ((addr >= start && addr < end) ||
- (addr2 >= start && addr2 < end) ||
- ((addr < start) && (addr2 >= end)));
+ return !(b1 <= a2 || a1 >= b2);
}
-static void check_for_illegal_area(struct device *dev, void *addr, u64 size)
+static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len)
{
- if (overlap(addr, size, _text, _etext) ||
- overlap(addr, size, __start_rodata, __end_rodata))
- err_printk(dev, NULL, "DMA-API: device driver maps "
- "memory from kernel text or rodata "
- "[addr=%p] [size=%llu]\n", addr, size);
+ if (overlap(addr, len, _text, _etext) ||
+ overlap(addr, len, __start_rodata, __end_rodata))
+ err_printk(dev, NULL, "DMA-API: device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len);
}
static void check_sync(struct device *dev,
@@ -969,7 +968,8 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
entry->type = dma_debug_single;
if (!PageHighMem(page)) {
- void *addr = ((char *)page_address(page)) + offset;
+ void *addr = page_address(page) + offset;
+
check_for_stack(dev, addr);
check_for_illegal_area(dev, addr, size);
}
^ permalink raw reply [flat|nested] 10+ messages in thread
* [GIT PULL] core kernel fixes
@ 2009-08-09 16:07 Ingo Molnar
2009-08-09 18:41 ` Darren Hart
0 siblings, 1 reply; 10+ messages in thread
From: Ingo Molnar @ 2009-08-09 16:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, Thomas Gleixner
Linus,
Please pull the latest core-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus
Thanks,
Ingo
------------------>
Darren Hart (2):
rtmutex: Avoid deadlock in rt_mutex_start_proxy_lock()
futex: Update woken requeued futex_q lock_ptr
Li Zefan (2):
lockdep: Fix file mode of lock_stat
lockdep: Fix typos in documentation
Documentation/lockdep-design.txt | 6 +++---
kernel/futex.c | 13 +++++++++----
kernel/lockdep_proc.c | 3 ++-
kernel/rtmutex.c | 4 +---
4 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt
index e20d913..abf768c 100644
--- a/Documentation/lockdep-design.txt
+++ b/Documentation/lockdep-design.txt
@@ -30,9 +30,9 @@ State
The validator tracks lock-class usage history into 4n + 1 separate state bits:
- 'ever held in STATE context'
-- 'ever head as readlock in STATE context'
-- 'ever head with STATE enabled'
-- 'ever head as readlock with STATE enabled'
+- 'ever held as readlock in STATE context'
+- 'ever held with STATE enabled'
+- 'ever held as readlock with STATE enabled'
Where STATE can be either one of (kernel/lockdep_states.h)
- hardirq
diff --git a/kernel/futex.c b/kernel/futex.c
index 0672ff8..57f5a80 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1010,19 +1010,24 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1,
* requeue_pi_wake_futex() - Wake a task that acquired the lock during requeue
* q: the futex_q
* key: the key of the requeue target futex
+ * hb: the hash_bucket of the requeue target futex
*
* During futex_requeue, with requeue_pi=1, it is possible to acquire the
* target futex if it is uncontended or via a lock steal. Set the futex_q key
* to the requeue target futex so the waiter can detect the wakeup on the right
* futex, but remove it from the hb and NULL the rt_waiter so it can detect
- * atomic lock acquisition. Must be called with the q->lock_ptr held.
+ * atomic lock acquisition. Set the q->lock_ptr to the requeue target hb->lock
+ * to protect access to the pi_state to fixup the owner later. Must be called
+ * with the q->lock_ptr held.
*/
static inline
-void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key)
+void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
+ struct futex_hash_bucket *hb)
{
drop_futex_key_refs(&q->key);
get_futex_key_refs(key);
q->key = *key;
+ q->lock_ptr = &hb->lock;
WARN_ON(plist_node_empty(&q->list));
plist_del(&q->list, &q->list.plist);
@@ -1088,7 +1093,7 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
set_waiters);
if (ret == 1)
- requeue_pi_wake_futex(top_waiter, key2);
+ requeue_pi_wake_futex(top_waiter, key2, hb2);
return ret;
}
@@ -1273,7 +1278,7 @@ retry_private:
this->task, 1);
if (ret == 1) {
/* We got the lock. */
- requeue_pi_wake_futex(this, &key2);
+ requeue_pi_wake_futex(this, &key2, hb2);
continue;
} else if (ret) {
/* -EDEADLK */
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index d7135aa..e94caa6 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -758,7 +758,8 @@ static int __init lockdep_proc_init(void)
&proc_lockdep_stats_operations);
#ifdef CONFIG_LOCK_STAT
- proc_create("lock_stat", S_IRUSR, NULL, &proc_lock_stat_operations);
+ proc_create("lock_stat", S_IRUSR | S_IWUSR, NULL,
+ &proc_lock_stat_operations);
#endif
return 0;
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index fcd107a..29bd4ba 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -1039,16 +1039,14 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
if (!rt_mutex_owner(lock) || try_to_steal_lock(lock, task)) {
/* We got the lock for task. */
debug_rt_mutex_lock(lock);
-
rt_mutex_set_owner(lock, task, 0);
-
+ spin_unlock(&lock->wait_lock);
rt_mutex_deadlock_account_lock(lock, task);
return 1;
}
ret = task_blocks_on_rt_mutex(lock, waiter, task, detect_deadlock);
-
if (ret && !waiter->task) {
/*
* Reset the return value. We might have
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [GIT PULL] core kernel fixes
2009-08-09 16:07 [GIT PULL] " Ingo Molnar
@ 2009-08-09 18:41 ` Darren Hart
2009-08-09 20:19 ` [GIT PULL, v2] " Ingo Molnar
0 siblings, 1 reply; 10+ messages in thread
From: Darren Hart @ 2009-08-09 18:41 UTC (permalink / raw)
To: Ingo Molnar; +Cc: lkml, , Thomas Gleixner, Linus Torvalds
Ingo Molnar wrote:
> Linus,
>
> Please pull the latest core-fixes-for-linus git tree from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus
>
> Thanks,
>
> Ingo
>
> ------------------>
> Darren Hart (2):
> rtmutex: Avoid deadlock in rt_mutex_start_proxy_lock()
> futex: Update woken requeued futex_q lock_ptr
Ingo, this still has the older version of:
"futex: Update woken requeued futex_q lock_ptr"
Please update to the resend on Aug 7:
Update futex_q lock_ptr on requeue proxy lock (resend)
From: Darren Hart <dvhltc@us.ibm.com>
futex_requeue() can acquire the lock on behalf of a waiter early on or during
the requeue loop if it is uncontended or in the event of a lock steal or owner
died. On wakeup, the waiter (in futex_wait_requeue_pi()) cleans up the pi_state
owner using the lock_ptr to protect against concurrent access to the pi_state.
The pi_state is hung off futex_q's on the requeue target futex hash bucket so
the lock_ptr needs to be updated accordingly.
The problem manifested by triggering the WARN_ON in lookup_pi_state() about the
pid != pi_state->owner->pid. With this patch, the pi_state is properly guarded
against concurrent access via the requeue target hb lock.
The astute reviewer may notice that there is a window of time between when
futex_requeue() unlocks the hb locks and when futex_wait_requeue_pi() will
acquire hb2->lock. During this time the pi_state and uval are not in sync with
the underlying rtmutex owner (but the uval does indicate there are waiters, so
no atomic changes will occur in userspace). However, this is not a problem.
Should a contending thread enter lookup_pi_state() and acquire hb2->lock before
the ownership is fixed up, it will find the pi_state hung off a waiter's
(possibly the pending owner's) futex_q and block on the rtmutex. Once
futex_wait_requeue_pi() fixes up the owner, it will also move the pi_state from
the old owner's task->pi_state_list to its own.
Signed-off-by: Darren Hart <dvhltc@us.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ingo Molnar <mingo@elte.hu>
CC: Eric Dumazet <eric.dumazet@gmail.com>
CC: Dinakar Guniguntala <dino@in.ibm.com>
CC: John Stultz <johnstul@us.ibm.com>
---
kernel/futex.c | 17 +++++++++++++----
1 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/kernel/futex.c b/kernel/futex.c
index abce822..df30983 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1059,15 +1059,19 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1,
* requeue_pi_wake_futex() - Wake a task that acquired the lock during requeue
* q: the futex_q
* key: the key of the requeue target futex
+ * hb: the hash_bucket of the requeue target futex
*
* During futex_requeue, with requeue_pi=1, it is possible to acquire the
* target futex if it is uncontended or via a lock steal. Set the futex_q key
* to the requeue target futex so the waiter can detect the wakeup on the right
* futex, but remove it from the hb and NULL the rt_waiter so it can detect
- * atomic lock acquisition. Must be called with the q->lock_ptr held.
+ * atomic lock acquisition. Set the q->lock_ptr to the requeue target hb->lock
+ * to protect access to the pi_state to fixup the owner later. Must be called
+ * with both q->lock_ptr and hb->lock held.
*/
static inline
-void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key)
+void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
+ struct futex_hash_bucket *hb)
{
drop_futex_key_refs(&q->key);
get_futex_key_refs(key);
@@ -1079,6 +1083,11 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key)
WARN_ON(!q->rt_waiter);
q->rt_waiter = NULL;
+ q->lock_ptr = &hb->lock;
+#ifdef CONFIG_DEBUG_PI_LIST
+ q->list.plist.slock = &hb->lock;
+#endif
+
wake_up_state(q->task, TASK_NORMAL);
}
@@ -1137,7 +1146,7 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
set_waiters);
if (ret == 1)
- requeue_pi_wake_futex(top_waiter, key2);
+ requeue_pi_wake_futex(top_waiter, key2, hb2);
return ret;
}
@@ -1323,7 +1332,7 @@ retry_private:
this->task, 1);
if (ret == 1) {
/* We got the lock. */
- requeue_pi_wake_futex(this, &key2);
+ requeue_pi_wake_futex(this, &key2, hb2);
continue;
} else if (ret) {
/* -EDEADLK */
--
Darren Hart
IBM Linux Technology Center
Real-Time Linux Team
^ permalink raw reply [flat|nested] 10+ messages in thread* [GIT PULL, v2] core kernel fixes
2009-08-09 18:41 ` Darren Hart
@ 2009-08-09 20:19 ` Ingo Molnar
0 siblings, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2009-08-09 20:19 UTC (permalink / raw)
To: Darren Hart; +Cc: lkml, , Thomas Gleixner, Linus Torvalds
* Darren Hart <dvhltc@us.ibm.com> wrote:
> Ingo Molnar wrote:
>> Linus,
>>
>> Please pull the latest core-fixes-for-linus git tree from:
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus
>>
>> Thanks,
>>
>> Ingo
>>
>> ------------------>
>> Darren Hart (2):
>> rtmutex: Avoid deadlock in rt_mutex_start_proxy_lock()
>> futex: Update woken requeued futex_q lock_ptr
>
> Ingo, this still has the older version of:
>
> "futex: Update woken requeued futex_q lock_ptr"
>
> Please update to the resend on Aug 7:
Resend usual means 'same stuff again' and since i already had the
first patch i skipped it. The usual way is to put 'v2' into the
subject or something. Anyway - v2 needs re-testing.
Linus, please pull this shortened tree instead (it has the final
commit removed):
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus-2
Thanks,
Ingo
------------------>
Darren Hart (1):
rtmutex: Avoid deadlock in rt_mutex_start_proxy_lock()
Li Zefan (2):
lockdep: Fix file mode of lock_stat
lockdep: Fix typos in documentation
Documentation/lockdep-design.txt | 6 +++---
kernel/lockdep_proc.c | 3 ++-
kernel/rtmutex.c | 4 +---
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt
index e20d913..abf768c 100644
--- a/Documentation/lockdep-design.txt
+++ b/Documentation/lockdep-design.txt
@@ -30,9 +30,9 @@ State
The validator tracks lock-class usage history into 4n + 1 separate state bits:
- 'ever held in STATE context'
-- 'ever head as readlock in STATE context'
-- 'ever head with STATE enabled'
-- 'ever head as readlock with STATE enabled'
+- 'ever held as readlock in STATE context'
+- 'ever held with STATE enabled'
+- 'ever held as readlock with STATE enabled'
Where STATE can be either one of (kernel/lockdep_states.h)
- hardirq
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index d7135aa..e94caa6 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -758,7 +758,8 @@ static int __init lockdep_proc_init(void)
&proc_lockdep_stats_operations);
#ifdef CONFIG_LOCK_STAT
- proc_create("lock_stat", S_IRUSR, NULL, &proc_lock_stat_operations);
+ proc_create("lock_stat", S_IRUSR | S_IWUSR, NULL,
+ &proc_lock_stat_operations);
#endif
return 0;
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index fcd107a..29bd4ba 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -1039,16 +1039,14 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
if (!rt_mutex_owner(lock) || try_to_steal_lock(lock, task)) {
/* We got the lock for task. */
debug_rt_mutex_lock(lock);
-
rt_mutex_set_owner(lock, task, 0);
-
+ spin_unlock(&lock->wait_lock);
rt_mutex_deadlock_account_lock(lock, task);
return 1;
}
ret = task_blocks_on_rt_mutex(lock, waiter, task, detect_deadlock);
-
if (ret && !waiter->task) {
/*
* Reset the return value. We might have
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-08-09 20:20 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-18 14:23 [GIT PULL] core kernel fixes Ingo Molnar
2009-05-18 15:48 ` Linus Torvalds
2009-05-18 19:20 ` Thomas Gleixner
2009-05-19 20:52 ` Linus Torvalds
2009-05-19 21:45 ` Thomas Gleixner
2009-05-19 22:20 ` Darren Hart
2009-05-18 16:59 ` [GIT PULL, v2] " Ingo Molnar
2009-06-21 10:55 Ingo Molnar
2009-07-10 16:28 [GIT PULL] " Ingo Molnar
2009-07-10 19:06 ` Linus Torvalds
2009-07-10 19:31 ` Ingo Molnar
2009-07-10 20:36 ` [GIT PULL, v2] " Ingo Molnar
2009-08-09 16:07 [GIT PULL] " Ingo Molnar
2009-08-09 18:41 ` Darren Hart
2009-08-09 20:19 ` [GIT PULL, v2] " Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®