]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-regressions.patch
- remove from HEAD
[packages/kernel.git] / kernel-regressions.patch
1 rom ae060e0b7bc071bd73dd5319b93c3344d9e10212 Mon Sep 17 00:00:00 2001
2 From: Manfred Spraul <manfred@colorfullife.com>
3 To: torvalds@linux-foundation.org
4 Cc: linux-kernel@vger.kernel.org
5 Cc: cebbert@redhat.com
6 Cc: airlied@gmail.com
7 Cc: akpm@linux-foundation.org
8 Bcc: manfred@colorfullife.com
9 Date: Wed, 10 Dec 2008 18:17:06 +0100
10 Subject: [PATCH] lib/idr.c: Fix bug introduced by RCU fix
11
12 The last patch to lib/idr.c caused a bug if idr_get_new_above() was
13 called on an empty idr:
14 Usually, nodes stay on the same layer. New layers are added to the top
15 of the tree.
16 The exception is idr_get_new_above() on an empty tree: In this case,
17 the new root node is first added on layer 0, then moved upwards.
18 p->layer was not updated.
19
20 As usual: You shall never rely on the source code comments, they
21 will only mislead you.
22
23 Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
24 ---
25  lib/idr.c |    8 +++++++-
26  1 files changed, 7 insertions(+), 1 deletions(-)
27
28 diff --git a/lib/idr.c b/lib/idr.c
29 index 7a785a0..1c4f928 100644
30 --- a/lib/idr.c
31 +++ b/lib/idr.c
32 @@ -220,8 +220,14 @@ build_up:
33          */
34         while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
35                 layers++;
36 -               if (!p->count)
37 +               if (!p->count) {
38 +                       /* special case: if the tree is currently empty,
39 +                        * then we grow the tree by moving the top node
40 +                        * upwards.
41 +                        */
42 +                       p->layer++;
43                         continue;
44 +               }
45                 if (!(new = get_from_free_list(idp))) {
46                         /*
47                          * The allocation failed.  If we built part of
48 -- 
49 1.5.6.5
50
51 From: Trond Myklebust <Trond.Myklebust@netapp.com>
52 Date: Thu, 20 Nov 2008 21:06:21 +0000 (-0500)
53 Subject: SUNRPC: Fix a performance regression in the RPC authentication code
54 X-Git-Tag: v2.6.28-rc6~4
55 X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=23918b03060f6e572168fdde1798a905679d2e06
56
57 SUNRPC: Fix a performance regression in the RPC authentication code
58
59 Fix a regression reported by Max Kellermann whereby kernel profiling
60 showed that his clients were spending 45% of their time in
61 rpcauth_lookup_credcache.
62
63 It turns out that although his processes had identical uid/gid/groups,
64 generic_match() was failing to detect this, because the task->group_info
65 pointers were not shared. This again lead to the creation of a huge number
66 of identical credentials at the RPC layer.
67
68 The regression is fixed by comparing the contents of task->group_info
69 if the actual pointers are not identical.
70
71 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
72 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
73 ---
74
75 diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
76 index 744b79f..4028502 100644
77 --- a/net/sunrpc/auth_generic.c
78 +++ b/net/sunrpc/auth_generic.c
79 @@ -133,13 +133,29 @@ static int
80  generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
81  {
82         struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
83 +       int i;
84  
85         if (gcred->acred.uid != acred->uid ||
86             gcred->acred.gid != acred->gid ||
87 -           gcred->acred.group_info != acred->group_info ||
88             gcred->acred.machine_cred != acred->machine_cred)
89 -               return 0;
90 +               goto out_nomatch;
91 +
92 +       /* Optimisation in the case where pointers are identical... */
93 +       if (gcred->acred.group_info == acred->group_info)
94 +               goto out_match;
95 +
96 +       /* Slow path... */
97 +       if (gcred->acred.group_info->ngroups != acred->group_info->ngroups)
98 +               goto out_nomatch;
99 +       for (i = 0; i < gcred->acred.group_info->ngroups; i++) {
100 +               if (GROUP_AT(gcred->acred.group_info, i) !=
101 +                               GROUP_AT(acred->group_info, i))
102 +                       goto out_nomatch;
103 +       }
104 +out_match:
105         return 1;
106 +out_nomatch:
107 +       return 0;
108  }
109  
110  void __init rpc_init_generic_auth(void)
This page took 0.040782 seconds and 3 git commands to generate.