* [PATCH 0/8] idr: fix & cleanup
@ 2014-04-18 12:49 Lai Jiangshan
2014-04-18 12:49 ` [PATCH 1/8] idr: fix overflow bug for the max-high layer Lai Jiangshan
` (8 more replies)
0 siblings, 9 replies; 38+ messages in thread
From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw)
To: Tejun Heo, linux-kernel; +Cc: Lai Jiangshan
Patch1 fix a bug caused by overflow.
Patch2,3 add checks for unallocated_id.
Patch4 changes to returned error code
Patch5-8 cleanup.
Lai Jiangshan (8):
idr: fix overflow bug for the max-high layer
idr: fix unexpected id-removal when idr_remove(unallocated_id)
idr: fix NULL pointer dereference when ida_remove(unallocated_id)
idr: fix idr_replace()'s returned error code
idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid.
idr: avoid ping-pong
idr: don't need to shink the free list when idr_remove()
idr: reduce the unneeded check in free_layer()
lib/idr.c | 58 +++++++++++++++++-----------------------------------------
1 files changed, 17 insertions(+), 41 deletions(-)
--
1.7.4.4
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 1/8] idr: fix overflow bug for the max-high layer 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 16:29 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 2/8] idr: fix unexpected id-removal when idr_remove(unallocated_id) Lai Jiangshan ` (7 subsequent siblings) 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, stable, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger In idr_replace(), when the top layer is the max-high layer(p->layer == 3), The "(1 << n)" will overflow and the result is 0, it causes idr_replace() return -EINVAL even the id is actually valid. The following test code shows it fails to replace the value for id=((1<<27)+42): static void test5(void) { int id; DEFINE_IDR(test_idr); #define TEST5_START ((1<<27)+42) /* use the highest layer */ printk(KERN_INFO "Start test5\n"); id = idr_alloc(&test_idr, (void *)1, TEST5_START, 0, GFP_KERNEL); BUG_ON(id != TEST5_START); TEST_BUG_ON(idr_replace(&test_idr, (void *)2, TEST5_START) != (void *)1); idr_destroy(&test_idr); printk(KERN_INFO "End of test5\n"); } Fixed the bug by using idr_max() instead of the incorrect open code. There is the same problem in sub_alloc(). The overflow causes sub_alloc() returns -EAGAIN unexpectedly. But the idr_get_empty_slot() will call it again with increased @id. So the bug is hided. CC: stable@vger.kernel.org Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 2642fa8..4df6792 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -249,7 +249,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa, id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1; /* if already at the top layer, we need to grow */ - if (id >= 1 << (idp->layers * IDR_BITS)) { + if (id > idr_max(idp->layers)) { *starting_id = id; return -EAGAIN; } @@ -811,12 +811,10 @@ void *idr_replace(struct idr *idp, void *ptr, int id) if (!p) return ERR_PTR(-EINVAL); - n = (p->layer+1) * IDR_BITS; - - if (id >= (1 << n)) + if (id > idr_max(p->layer + 1)) return ERR_PTR(-EINVAL); - n -= IDR_BITS; + n = p->layer * IDR_BITS; while ((n > 0) && p) { p = p->ary[(id >> n) & IDR_MASK]; n -= IDR_BITS; -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 1/8] idr: fix overflow bug for the max-high layer 2014-04-18 12:49 ` [PATCH 1/8] idr: fix overflow bug for the max-high layer Lai Jiangshan @ 2014-04-18 16:29 ` Tejun Heo 2014-04-18 17:08 ` Lai Jiangshan 0 siblings, 1 reply; 38+ messages in thread From: Tejun Heo @ 2014-04-18 16:29 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, stable, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger Hello, Subject: idr: fix overflow bug during maximum ID calculation at maximum height On Fri, Apr 18, 2014 at 08:49:48PM +0800, Lai Jiangshan wrote: > In idr_replace(), when the top layer is the max-high layer(p->layer == 3), > The "(1 << n)" will overflow and the result is 0, it causes idr_replace() > return -EINVAL even the id is actually valid. idr_replace() open-codes the logic to calculate the maximum valid ID given the height of the idr tree; unfortunately, the open-coded logic doesn't account for the fact that the top layer may have unused slots and over-shifts the limit to zero when the tree is at its maximum height. > The following test code shows it fails to replace the value for id=((1<<27)+42): > > static void test5(void) > { > int id; > DEFINE_IDR(test_idr); > #define TEST5_START ((1<<27)+42) /* use the highest layer */ > > printk(KERN_INFO "Start test5\n"); > id = idr_alloc(&test_idr, (void *)1, TEST5_START, 0, GFP_KERNEL); > BUG_ON(id != TEST5_START); > TEST_BUG_ON(idr_replace(&test_idr, (void *)2, TEST5_START) != (void *)1); > idr_destroy(&test_idr); > printk(KERN_INFO "End of test5\n"); > } > > Fixed the bug by using idr_max() instead of the incorrect open code. Fix the bug by using idr_max() which correctly takes into account the maximum allowed shift. > There is the same problem in sub_alloc(). The overflow causes sub_alloc() > returns -EAGAIN unexpectedly. But the idr_get_empty_slot() will call it > again with increased @id. So the bug is hided. sub_alloc() shares the same problem and may incorrectly fail with -EAGAIN; however, this bug doesn't affect correct operation because idr_get_empty_slot(), which already uses idr_max(), retries with the increased @id in such cases. > CC: stable@vger.kernel.org > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 1/8] idr: fix overflow bug for the max-high layer 2014-04-18 16:29 ` Tejun Heo @ 2014-04-18 17:08 ` Lai Jiangshan 2014-04-18 17:10 ` Tejun Heo 0 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 17:08 UTC (permalink / raw) To: Tejun Heo Cc: LKML, stable, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Sat, Apr 19, 2014 at 12:29 AM, Tejun Heo <tj@kernel.org> wrote: > Hello, Hi, Should I resend the patch with your updated changelog? Or something else I need to do? > > Subject: idr: fix overflow bug during maximum ID calculation at maximum height > > On Fri, Apr 18, 2014 at 08:49:48PM +0800, Lai Jiangshan wrote: >> In idr_replace(), when the top layer is the max-high layer(p->layer == 3), >> The "(1 << n)" will overflow and the result is 0, it causes idr_replace() >> return -EINVAL even the id is actually valid. > > idr_replace() open-codes the logic to calculate the maximum valid ID > given the height of the idr tree; unfortunately, the open-coded logic > doesn't account for the fact that the top layer may have unused slots > and over-shifts the limit to zero when the tree is at its maximum > height. > >> The following test code shows it fails to replace the value for id=((1<<27)+42): >> >> static void test5(void) >> { >> int id; >> DEFINE_IDR(test_idr); >> #define TEST5_START ((1<<27)+42) /* use the highest layer */ >> >> printk(KERN_INFO "Start test5\n"); >> id = idr_alloc(&test_idr, (void *)1, TEST5_START, 0, GFP_KERNEL); >> BUG_ON(id != TEST5_START); >> TEST_BUG_ON(idr_replace(&test_idr, (void *)2, TEST5_START) != (void *)1); >> idr_destroy(&test_idr); >> printk(KERN_INFO "End of test5\n"); >> } Does the above testing code need to be kept in the changelog. Thanks, Lai >> >> Fixed the bug by using idr_max() instead of the incorrect open code. > > Fix the bug by using idr_max() which correctly takes into account the > maximum allowed shift. > >> There is the same problem in sub_alloc(). The overflow causes sub_alloc() >> returns -EAGAIN unexpectedly. But the idr_get_empty_slot() will call it >> again with increased @id. So the bug is hided. > > sub_alloc() shares the same problem and may incorrectly fail with > -EAGAIN; however, this bug doesn't affect correct operation because > idr_get_empty_slot(), which already uses idr_max(), retries with the > increased @id in such cases. > >> CC: stable@vger.kernel.org >> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> > > Acked-by: Tejun Heo <tj@kernel.org> > > Thanks. > > -- > tejun > -- > 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/ ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 1/8] idr: fix overflow bug for the max-high layer 2014-04-18 17:08 ` Lai Jiangshan @ 2014-04-18 17:10 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-18 17:10 UTC (permalink / raw) To: Lai Jiangshan Cc: LKML, stable, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Sat, Apr 19, 2014 at 01:08:46AM +0800, Lai Jiangshan wrote: > On Sat, Apr 19, 2014 at 12:29 AM, Tejun Heo <tj@kernel.org> wrote: > > Hello, > > Hi, > > Should I resend the patch with your updated changelog? > Or something else I need to do? Yeah, please resend with the description updated. > >> static void test5(void) > >> { > >> int id; > >> DEFINE_IDR(test_idr); > >> #define TEST5_START ((1<<27)+42) /* use the highest layer */ > >> > >> printk(KERN_INFO "Start test5\n"); > >> id = idr_alloc(&test_idr, (void *)1, TEST5_START, 0, GFP_KERNEL); > >> BUG_ON(id != TEST5_START); > >> TEST_BUG_ON(idr_replace(&test_idr, (void *)2, TEST5_START) != (void *)1); > >> idr_destroy(&test_idr); > >> printk(KERN_INFO "End of test5\n"); > >> } > > Does the above testing code need to be kept in the changelog. Yeah, why not? It makes what's failing very clear. Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 2/8] idr: fix unexpected id-removal when idr_remove(unallocated_id) 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan 2014-04-18 12:49 ` [PATCH 1/8] idr: fix overflow bug for the max-high layer Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 16:57 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 3/8] idr: fix NULL pointer dereference when ida_remove(unallocated_id) Lai Jiangshan ` (6 subsequent siblings) 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger If unallocated_id = (ANY * idr_max(idp->layers) + existed_id) is passed to idr_remove(). The existed_id will be removed unexpected. The following test shows this unexpected id-removal: static void test4(void) { int id; DEFINE_IDR(test_idr); printk(KERN_INFO "Start test4\n"); id = idr_alloc(&test_idr, (void *)1, 42, 43, GFP_KERNEL); BUG_ON(id != 42); idr_remove(&test_idr, 42 + IDR_SIZE); TEST_BUG_ON(idr_find(&test_idr, 42) != (void *)1); idr_destroy(&test_idr); printk(KERN_INFO "End of test4\n"); } It only happens when unallocated_id, it is caller's fault. It is not a bug. But it is better to add the proper check and complains instead of removing an existed_id silently. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 4df6792..a28036d 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -562,6 +562,11 @@ void idr_remove(struct idr *idp, int id) if (id < 0) return; + if (id > idr_max(idp->layers)) { + idr_remove_warning(id); + return; + } + sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); if (idp->top && idp->top->count == 1 && (idp->layers > 1) && idp->top->ary[0]) { -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 2/8] idr: fix unexpected id-removal when idr_remove(unallocated_id) 2014-04-18 12:49 ` [PATCH 2/8] idr: fix unexpected id-removal when idr_remove(unallocated_id) Lai Jiangshan @ 2014-04-18 16:57 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-18 16:57 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Fri, Apr 18, 2014 at 08:49:49PM +0800, Lai Jiangshan wrote: > If unallocated_id = (ANY * idr_max(idp->layers) + existed_id) is passed existing_id > to idr_remove(). The existed_id will be removed unexpected. ditto. > > The following test shows this unexpected id-removal: > > static void test4(void) > { > int id; > DEFINE_IDR(test_idr); > > printk(KERN_INFO "Start test4\n"); > id = idr_alloc(&test_idr, (void *)1, 42, 43, GFP_KERNEL); > BUG_ON(id != 42); > idr_remove(&test_idr, 42 + IDR_SIZE); > TEST_BUG_ON(idr_find(&test_idr, 42) != (void *)1); > idr_destroy(&test_idr); > printk(KERN_INFO "End of test4\n"); > } > > It only happens when unallocated_id, it is caller's fault. It is not > a bug. But it is better to add the proper check and complains instead complain > of removing an existed_id silently. existing_id > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 3/8] idr: fix NULL pointer dereference when ida_remove(unallocated_id) 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan 2014-04-18 12:49 ` [PATCH 1/8] idr: fix overflow bug for the max-high layer Lai Jiangshan 2014-04-18 12:49 ` [PATCH 2/8] idr: fix unexpected id-removal when idr_remove(unallocated_id) Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 17:09 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 4/8] idr: fix idr_replace()'s returned error code Lai Jiangshan ` (5 subsequent siblings) 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger If the ida has at least one existed_id, and when an special unallocated_id is passed to the ida_remove(), the system will crash because it hits NULL pointer dereference. This special unallocated_id is that it shares the same lowest idr layer with an exsited_id, but the idr slot is different(if the unallocated_id is allocated). In this case the supposed idr slot of the unallocated_id is NULL, It means @bitmap == NULL, and when the code dereference it, it crash the kernel. See the test code: static void test3(void) { int id; DEFINE_IDA(test_ida); printk(KERN_INFO "Start test3\n"); if (ida_pre_get(&test_ida, GFP_KERNEL) < 0) return; if (ida_get_new(&test_ida, &id) < 0) return; ida_remove(&test_ida, 4000); /* bug: null deference here */ printk(KERN_INFO "End of test3\n"); } It only happens when unallocated_id, it is caller's fault. It is not a bug. But it is better to add the proper check and complains instead of crashing the kernel. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index a28036d..d200d67 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -1045,7 +1045,7 @@ void ida_remove(struct ida *ida, int id) __clear_bit(n, p->bitmap); bitmap = (void *)p->ary[n]; - if (!test_bit(offset, bitmap->bitmap)) + if (!bitmap || !test_bit(offset, bitmap->bitmap)) goto err; /* update bitmap and remove it if empty */ -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 3/8] idr: fix NULL pointer dereference when ida_remove(unallocated_id) 2014-04-18 12:49 ` [PATCH 3/8] idr: fix NULL pointer dereference when ida_remove(unallocated_id) Lai Jiangshan @ 2014-04-18 17:09 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-18 17:09 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Fri, Apr 18, 2014 at 08:49:50PM +0800, Lai Jiangshan wrote: > If the ida has at least one existed_id, and when an special unallocated_id existing id or allocated id when an unallocated id which meets a certain condition is passed to... > is passed to the ida_remove(), the system will crash because it hits NULL > pointer dereference. > > This special unallocated_id is that it shares the same lowest idr layer with The condition is that the ID shares the... > an exsited_id, but the idr slot is different(if the unallocated_id is allocated). the existing ID, would be different if the unallocated ID were to be allocated. > In this case the supposed idr slot of the unallocated_id is NULL, matching for > It means @bitmap == NULL, and when the code dereference it, it crash the kernel. causing @bitmap to be NULL which the function dereferences without checking crashing the kernel. > > See the test code: > > static void test3(void) > { > int id; > DEFINE_IDA(test_ida); > > printk(KERN_INFO "Start test3\n"); > if (ida_pre_get(&test_ida, GFP_KERNEL) < 0) return; > if (ida_get_new(&test_ida, &id) < 0) return; > ida_remove(&test_ida, 4000); /* bug: null deference here */ > printk(KERN_INFO "End of test3\n"); > } > > It only happens when unallocated_id, it is caller's fault. It is not It happens only when the caller tries to free an unallocated ID which is the caller's fault. > a bug. But it is better to add the proper check and complains instead and complain rather than crashing the kernel > of crashing the kernel. > > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 4/8] idr: fix idr_replace()'s returned error code 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan ` (2 preceding siblings ...) 2014-04-18 12:49 ` [PATCH 3/8] idr: fix NULL pointer dereference when ida_remove(unallocated_id) Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 17:12 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 5/8] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan ` (4 subsequent siblings) 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger When the smaller id is not found, idr_replace() returns -ENOENT. But when the id is bigger enough, idr_replace() returns -EINVAL, actually there is no difference between these two kinds of ids. These are all unallocated id, the return values of the idr_replace() for these ids should be the same: -ENOENT. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index d200d67..104f87f 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -814,10 +814,10 @@ void *idr_replace(struct idr *idp, void *ptr, int id) p = idp->top; if (!p) - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOENT); if (id > idr_max(p->layer + 1)) - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOENT); n = p->layer * IDR_BITS; while ((n > 0) && p) { -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 4/8] idr: fix idr_replace()'s returned error code 2014-04-18 12:49 ` [PATCH 4/8] idr: fix idr_replace()'s returned error code Lai Jiangshan @ 2014-04-18 17:12 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-18 17:12 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Fri, Apr 18, 2014 at 08:49:51PM +0800, Lai Jiangshan wrote: > When the smaller id is not found, idr_replace() returns -ENOENT. > But when the id is bigger enough, idr_replace() returns -EINVAL, > actually there is no difference between these two kinds of ids. > > These are all unallocated id, the return values of the idr_replace() > for these ids should be the same: -ENOENT. > > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 5/8] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid. 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan ` (3 preceding siblings ...) 2014-04-18 12:49 ` [PATCH 4/8] idr: fix idr_replace()'s returned error code Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 17:14 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 6/8] idr: avoid ping-pong Lai Jiangshan ` (3 subsequent siblings) 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger When the arguments passed by the caller are invalid, WARN_ON_ONCE() is proper than BUG_ON() which may crash the kernel. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 104f87f..e4f9965 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -1093,13 +1093,14 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, unsigned int max; unsigned long flags; - BUG_ON((int)start < 0); - BUG_ON((int)end < 0); + if (WARN_ON_ONCE(((int)start < 0) || ((int)end < 0))) + return -EINVAL; if (end == 0) max = 0x80000000; else { - BUG_ON(end < start); + if (WARN_ON_ONCE(end < start)) + return -EINVAL; max = end - 1; } @@ -1135,7 +1136,7 @@ void ida_simple_remove(struct ida *ida, unsigned int id) { unsigned long flags; - BUG_ON((int)id < 0); + WARN_ON_ONCE((int)id < 0); spin_lock_irqsave(&simple_ida_lock, flags); ida_remove(ida, id); spin_unlock_irqrestore(&simple_ida_lock, flags); -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 5/8] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid. 2014-04-18 12:49 ` [PATCH 5/8] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan @ 2014-04-18 17:14 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-18 17:14 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Fri, Apr 18, 2014 at 08:49:52PM +0800, Lai Jiangshan wrote: > @@ -1135,7 +1136,7 @@ void ida_simple_remove(struct ida *ida, unsigned int id) > { > unsigned long flags; > > - BUG_ON((int)id < 0); > + WARN_ON_ONCE((int)id < 0); Shouldn't this be moved to ida_remove()? Also, it probably should return afterwards? Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 6/8] idr: avoid ping-pong 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan ` (4 preceding siblings ...) 2014-04-18 12:49 ` [PATCH 5/8] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 17:17 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 7/8] idr: don't need to shink the free list when idr_remove() Lai Jiangshan ` (2 subsequent siblings) 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger The ida callers always calls ida_pre_get() before ida_get_new*(). ida_pre_get() will do layer allocation, and ida_get_new*() will do layer removal. It causes an unneeded ping-pong. The speculative layer removal in ida_get_new*() can't result expected optimization. So we remove the unneeded layer removal in ida_get_new*(). Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 11 ----------- 1 files changed, 0 insertions(+), 11 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index e4f9965..be0b6ff 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -1001,17 +1001,6 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) *p_id = id; - /* Each leaf node can handle nearly a thousand slots and the - * whole idea of ida is to have small memory foot print. - * Throw away extra resources one by one after each successful - * allocation. - */ - if (ida->idr.id_free_cnt || ida->free_bitmap) { - struct idr_layer *p = get_from_free_list(&ida->idr); - if (p) - kmem_cache_free(idr_layer_cache, p); - } - return 0; } EXPORT_SYMBOL(ida_get_new_above); -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 6/8] idr: avoid ping-pong 2014-04-18 12:49 ` [PATCH 6/8] idr: avoid ping-pong Lai Jiangshan @ 2014-04-18 17:17 ` Tejun Heo 2014-04-19 10:43 ` Lai Jiangshan 0 siblings, 1 reply; 38+ messages in thread From: Tejun Heo @ 2014-04-18 17:17 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Fri, Apr 18, 2014 at 08:49:53PM +0800, Lai Jiangshan wrote: > The ida callers always calls ida_pre_get() before ida_get_new*(). > ida_pre_get() will do layer allocation, and ida_get_new*() will do layer removal. > > It causes an unneeded ping-pong. The speculative layer removal in > ida_get_new*() can't result expected optimization. > > So we remove the unneeded layer removal in ida_get_new*(). But the as comment says, ida doesn't want to keep extra layers around as it wants to keep its memory footprint minimal. I think the right thing to do is implementing ida_preload() which is simliar to idr_preload() and do away with per-ida layer cache. Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 6/8] idr: avoid ping-pong 2014-04-18 17:17 ` Tejun Heo @ 2014-04-19 10:43 ` Lai Jiangshan 2014-04-19 13:01 ` Tejun Heo 0 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 10:43 UTC (permalink / raw) To: Tejun Heo Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On 04/19/2014 01:17 AM, Tejun Heo wrote: > On Fri, Apr 18, 2014 at 08:49:53PM +0800, Lai Jiangshan wrote: >> The ida callers always calls ida_pre_get() before ida_get_new*(). >> ida_pre_get() will do layer allocation, and ida_get_new*() will do layer removal. >> >> It causes an unneeded ping-pong. The speculative layer removal in >> ida_get_new*() can't result expected optimization. >> >> So we remove the unneeded layer removal in ida_get_new*(). > > But the as comment says, ida doesn't want to keep extra layers around > as it wants to keep its memory footprint minimal. It only frees one layer. And the ida_pre_get() for the next ida_get_new*() will allocation it back again. The aim "Throw away extra resources one by one" can't be achieved. It can't keep its memory footprint minimal. > I think the right > thing to do is implementing ida_preload() which is simliar to > idr_preload() and do away with per-ida layer cache. Yes and no. We need a static private ida_preload() for ida_simple_get() only. Because the IDA doesn't have any query-function, so IDA's own synchronization is enough for all use cases, IDA should off-loads the caller's synchronization burden. In my todo-list, IDA only needs the following functions. other functions will be deprecated and scheduled to be removed: void ida_destroy(struct ida *ida); void ida_init(struct ida *ida); int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, gfp_t gfp_mask); void ida_simple_remove(struct ida *ida, unsigned int id); (I don't think we need any query-function, But...) If in the future we need some query-functions such as: ida_is_this_id_allocated() ida_find_next_[un]allocated_id(), In this case, we can expose the ida_preload() and ida_alloc() at the same time that we introduce the query-functions. Any thought? But we need to remove this unneeded ping-pong despite of any plan. Thanks, Lai ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 6/8] idr: avoid ping-pong 2014-04-19 10:43 ` Lai Jiangshan @ 2014-04-19 13:01 ` Tejun Heo 2014-04-19 14:23 ` Lai Jiangshan 0 siblings, 1 reply; 38+ messages in thread From: Tejun Heo @ 2014-04-19 13:01 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger Hello, On Sat, Apr 19, 2014 at 06:43:41PM +0800, Lai Jiangshan wrote: > On 04/19/2014 01:17 AM, Tejun Heo wrote: > It only frees one layer. And the ida_pre_get() for the next ida_get_new*() > will allocation it back again. The aim "Throw away extra resources one by one" > can't be achieved. It can't keep its memory footprint minimal. Isn't the point not keeping the memory around per-ida between allocations which can be arbitrarily long? Why isn't it achieved? > > I think the right > > thing to do is implementing ida_preload() which is simliar to > > idr_preload() and do away with per-ida layer cache. > > Yes and no. > > We need a static private ida_preload() for ida_simple_get() only. > > Because the IDA doesn't have any query-function, so IDA's own synchronization > is enough for all use cases, IDA should off-loads the caller's > synchronization burden. Hmmm? And why can't that use preload on its own? > In my todo-list, IDA only needs the following functions. other functions > will be deprecated and scheduled to be removed: > void ida_destroy(struct ida *ida); > void ida_init(struct ida *ida); > int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, > gfp_t gfp_mask); > void ida_simple_remove(struct ida *ida, unsigned int id); > > (I don't think we need any query-function, But...) > If in the future we need some query-functions such as: > ida_is_this_id_allocated() > ida_find_next_[un]allocated_id(), > In this case, we can expose the ida_preload() and ida_alloc() at the same time that > we introduce the query-functions. Regardless of interface, we can still switch to per-cpu layer caching which would make this per-ida allocation issue go away. I'd much prefer to see that than debating the (dis)merits of this patch. Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 6/8] idr: avoid ping-pong 2014-04-19 13:01 ` Tejun Heo @ 2014-04-19 14:23 ` Lai Jiangshan 0 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 14:23 UTC (permalink / raw) To: Tejun Heo Cc: LKML, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Sat, Apr 19, 2014 at 9:01 PM, Tejun Heo <tj@kernel.org> wrote: > Hello, > > On Sat, Apr 19, 2014 at 06:43:41PM +0800, Lai Jiangshan wrote: >> On 04/19/2014 01:17 AM, Tejun Heo wrote: >> It only frees one layer. And the ida_pre_get() for the next ida_get_new*() >> will allocation it back again. The aim "Throw away extra resources one by one" >> can't be achieved. It can't keep its memory footprint minimal. > > Isn't the point not keeping the memory around per-ida between > allocations which can be arbitrarily long? Why isn't it achieved? "Throw away one layer" is achieved. "one by one" can't be achieved. > >> > I think the right >> > thing to do is implementing ida_preload() which is simliar to >> > idr_preload() and do away with per-ida layer cache. >> >> Yes and no. Yes: I agree to add ida_preload(). No: Because I think we don't need to expose ida_preload(). >> >> We need a static private ida_preload() for ida_simple_get() only. >> >> Because the IDA doesn't have any query-function, so IDA's own synchronization >> is enough for all use cases, IDA should off-loads the caller's >> synchronization burden. > > Hmmm? And why can't that use preload on its own? We need to use preload for ida_simple_get(). But we don't need to expose the ida_preload() if we kill the ida_get_new*() APIs. (The reason why we can kill the ida_get_new*() is explained below.) > >> In my todo-list, IDA only needs the following functions. other functions >> will be deprecated and scheduled to be removed: >> void ida_destroy(struct ida *ida); >> void ida_init(struct ida *ida); >> int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, >> gfp_t gfp_mask); >> void ida_simple_remove(struct ida *ida, unsigned int id); >> >> (I don't think we need any query-function, But...) >> If in the future we need some query-functions such as: >> ida_is_this_id_allocated() >> ida_find_next_[un]allocated_id(), >> In this case, we can expose the ida_preload() and ida_alloc() at the same time that >> we introduce the query-functions. > > Regardless of interface, we can still switch to per-cpu layer caching > which would make this per-ida allocation issue go away. agree. > I'd much > prefer to see that than debating the (dis)merits of this patch. agree. Please drop this patch. It will be better if we will cleanup it(and all free list related code) after ida_preload() is added. Thanks Lai > > Thanks. > > -- > tejun > -- > 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/ ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 7/8] idr: don't need to shink the free list when idr_remove() 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan ` (5 preceding siblings ...) 2014-04-18 12:49 ` [PATCH 6/8] idr: avoid ping-pong Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 17:19 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 8/8] idr: reduce the unneeded check in free_layer() Lai Jiangshan 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger After idr subsystem is changed to RCU-awared, the free layer will not go to the free list. The free list will not be filled up when idr_remove(). So we don't need to shink it too. "#ifndef TEST" can't work for user space test now, just remove it. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 17 ----------------- 1 files changed, 0 insertions(+), 17 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index be0b6ff..314ea5f 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -18,19 +18,11 @@ * pointer or what ever, we treat it as a (void *). You can pass this * id to a user for him to pass back at a later time. You then pass * that id to this code and it returns your pointer. - - * You can release ids at any time. When all ids are released, most of - * the memory is returned (we keep MAX_IDR_FREE) in a local pool so we - * don't need to go to the memory "store" during an id allocate, just - * so you don't need to be too concerned about locking and conflicts - * with the slab allocator. */ -#ifndef TEST // to test in user space... #include <linux/slab.h> #include <linux/init.h> #include <linux/export.h> -#endif #include <linux/err.h> #include <linux/string.h> #include <linux/idr.h> @@ -584,15 +576,6 @@ void idr_remove(struct idr *idp, int id) bitmap_clear(to_free->bitmap, 0, IDR_SIZE); free_layer(idp, to_free); } - while (idp->id_free_cnt >= MAX_IDR_FREE) { - p = get_from_free_list(idp); - /* - * Note: we don't call the rcu callback here, since the only - * layers that fall into the freelist are those that have been - * preallocated. - */ - kmem_cache_free(idr_layer_cache, p); - } return; } EXPORT_SYMBOL(idr_remove); -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 7/8] idr: don't need to shink the free list when idr_remove() 2014-04-18 12:49 ` [PATCH 7/8] idr: don't need to shink the free list when idr_remove() Lai Jiangshan @ 2014-04-18 17:19 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-18 17:19 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Fri, Apr 18, 2014 at 08:49:54PM +0800, Lai Jiangshan wrote: > After idr subsystem is changed to RCU-awared, the free layer will not go to > the free list. The free list will not be filled up when idr_remove(). > So we don't need to shink it too. > > "#ifndef TEST" can't work for user space test now, just remove it. Maybe put this in a separate patch? > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 8/8] idr: reduce the unneeded check in free_layer() 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan ` (6 preceding siblings ...) 2014-04-18 12:49 ` [PATCH 7/8] idr: don't need to shink the free list when idr_remove() Lai Jiangshan @ 2014-04-18 12:49 ` Lai Jiangshan 2014-04-18 17:21 ` Tejun Heo 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-18 12:49 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger If "idr->hint == p" is true, it also implies "idr->hint" is true(not NULL). Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 314ea5f..08d010c 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -143,7 +143,7 @@ static void idr_layer_rcu_free(struct rcu_head *head) static inline void free_layer(struct idr *idr, struct idr_layer *p) { - if (idr->hint && idr->hint == p) + if (idr->hint == p) RCU_INIT_POINTER(idr->hint, NULL); call_rcu(&p->rcu_head, idr_layer_rcu_free); } -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 8/8] idr: reduce the unneeded check in free_layer() 2014-04-18 12:49 ` [PATCH 8/8] idr: reduce the unneeded check in free_layer() Lai Jiangshan @ 2014-04-18 17:21 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-18 17:21 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Fri, Apr 18, 2014 at 08:49:55PM +0800, Lai Jiangshan wrote: > If "idr->hint == p" is true, it also implies "idr->hint" is true(not NULL). > > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 0/9 V2] idr: fix & cleanup 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan ` (7 preceding siblings ...) 2014-04-18 12:49 ` [PATCH 8/8] idr: reduce the unneeded check in free_layer() Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 1/9 V2] idr: fix overflow bug during maximum ID calculation at maximum height Lai Jiangshan ` (8 more replies) 8 siblings, 9 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel; +Cc: Lai Jiangshan Patch1 fix a bug caused by overflow. Patch2,3 add checks for unallocated_id. Patch4 changes to returned error code Patch5-9 cleanup. Lai Jiangshan (9): idr: fix overflow bug during maximum ID calculation at maximum height idr: fix unexpected ID-removal when idr_remove(unallocated_id) **^^also consider ida_remove() idr: fix NULL pointer dereference when ida_remove(unallocated_id) idr: fix idr_replace()'s returned error code idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid. **^^move the test into ida_remove() as tj suggested. idr: avoid ping-pong idr: don't need to shink the free list when idr_remove() **^^split idr: reduce the unneeded check in free_layer() idr: remove useless C-PreProcessor branch **^^new lib/idr.c | 66 +++++++++++++++++++++--------------------------------------- 1 files changed, 23 insertions(+), 43 deletions(-) -- 1.7.4.4 ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 1/9 V2] idr: fix overflow bug during maximum ID calculation at maximum height 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 2/9 V2] idr: fix unexpected ID-removal when idr_remove(unallocated_id) Lai Jiangshan ` (7 subsequent siblings) 8 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, stable, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger idr_replace() open-codes the logic to calculate the maximum valid ID given the height of the idr tree; unfortunately, the open-coded logic doesn't account for the fact that the top layer may have unused slots and over-shifts the limit to zero when the tree is at its maximum height. The following test code shows it fails to replace the value for id=((1<<27)+42): static void test5(void) { int id; DEFINE_IDR(test_idr); #define TEST5_START ((1<<27)+42) /* use the highest layer */ printk(KERN_INFO "Start test5\n"); id = idr_alloc(&test_idr, (void *)1, TEST5_START, 0, GFP_KERNEL); BUG_ON(id != TEST5_START); TEST_BUG_ON(idr_replace(&test_idr, (void *)2, TEST5_START) != (void *)1); idr_destroy(&test_idr); printk(KERN_INFO "End of test5\n"); } Fix the bug by using idr_max() which correctly takes into account the maximum allowed shift. sub_alloc() shares the same problem and may incorrectly fail with -EAGAIN; however, this bug doesn't affect correct operation because idr_get_empty_slot(), which already uses idr_max(), retries with the increased @id in such cases. tj: Updated patch description. CC: stable@vger.kernel.org Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> --- lib/idr.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 2642fa8..4df6792 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -249,7 +249,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa, id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1; /* if already at the top layer, we need to grow */ - if (id >= 1 << (idp->layers * IDR_BITS)) { + if (id > idr_max(idp->layers)) { *starting_id = id; return -EAGAIN; } @@ -811,12 +811,10 @@ void *idr_replace(struct idr *idp, void *ptr, int id) if (!p) return ERR_PTR(-EINVAL); - n = (p->layer+1) * IDR_BITS; - - if (id >= (1 << n)) + if (id > idr_max(p->layer + 1)) return ERR_PTR(-EINVAL); - n -= IDR_BITS; + n = p->layer * IDR_BITS; while ((n > 0) && p) { p = p->ary[(id >> n) & IDR_MASK]; n -= IDR_BITS; -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 2/9 V2] idr: fix unexpected ID-removal when idr_remove(unallocated_id) 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan 2014-04-19 11:38 ` [PATCH 1/9 V2] idr: fix overflow bug during maximum ID calculation at maximum height Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 3/9 V2] idr: fix NULL pointer dereference when ida_remove(unallocated_id) Lai Jiangshan ` (6 subsequent siblings) 8 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger If unallocated_id = (ANY * idr_max(idp->layers) + existing_id) is passed to idr_remove(). The existing_id will be removed unexpectedly. The following test shows this unexpected id-removal: static void test4(void) { int id; DEFINE_IDR(test_idr); printk(KERN_INFO "Start test4\n"); id = idr_alloc(&test_idr, (void *)1, 42, 43, GFP_KERNEL); BUG_ON(id != 42); idr_remove(&test_idr, 42 + IDR_SIZE); TEST_BUG_ON(idr_find(&test_idr, 42) != (void *)1); idr_destroy(&test_idr); printk(KERN_INFO "End of test4\n"); } ida_remove() shares the similar problem. It happens only when the caller tries to free an unallocated ID which is the caller's fault. It is not a bug. But it is better to add the proper check and complain rather than removing an existing_id silently. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> --- lib/idr.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 4df6792..c4afd94 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -562,6 +562,11 @@ void idr_remove(struct idr *idp, int id) if (id < 0) return; + if (id > idr_max(idp->layers)) { + idr_remove_warning(id); + return; + } + sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); if (idp->top && idp->top->count == 1 && (idp->layers > 1) && idp->top->ary[0]) { @@ -1025,6 +1030,9 @@ void ida_remove(struct ida *ida, int id) int n; struct ida_bitmap *bitmap; + if (idr_id > idr_max(ida->idr.layers)) + goto err; + /* clear full bits while looking up the leaf idr_layer */ while ((shift > 0) && p) { n = (idr_id >> shift) & IDR_MASK; -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 3/9 V2] idr: fix NULL pointer dereference when ida_remove(unallocated_id) 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan 2014-04-19 11:38 ` [PATCH 1/9 V2] idr: fix overflow bug during maximum ID calculation at maximum height Lai Jiangshan 2014-04-19 11:38 ` [PATCH 2/9 V2] idr: fix unexpected ID-removal when idr_remove(unallocated_id) Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 4/9 V2] idr: fix idr_replace()'s returned error code Lai Jiangshan ` (5 subsequent siblings) 8 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger If the ida has at least one existing id, and when an unallocated ID which meets a certain condition is passed to the ida_remove(), the system will crash because it hits NULL pointer dereference. The condition is that the unallocated ID shares the same lowest idr layer with the existing ID, but the idr slot would be different if the unallocated ID were to be allocated. In this case the matching idr slot for the unallocated_id is NULL, causing @bitmap to be NULL which the function dereferences without checking crashing the kernel. See the test code: static void test3(void) { int id; DEFINE_IDA(test_ida); printk(KERN_INFO "Start test3\n"); if (ida_pre_get(&test_ida, GFP_KERNEL) < 0) return; if (ida_get_new(&test_ida, &id) < 0) return; ida_remove(&test_ida, 4000); /* bug: null deference here */ printk(KERN_INFO "End of test3\n"); } It happens only when the caller tries to free an unallocated ID which is the caller's fault. It is not a bug. But it is better to add the proper check and complain rather than crashing the kernel. tj: Updated patch description. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> --- lib/idr.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index c4afd94..36ff732 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -1048,7 +1048,7 @@ void ida_remove(struct ida *ida, int id) __clear_bit(n, p->bitmap); bitmap = (void *)p->ary[n]; - if (!test_bit(offset, bitmap->bitmap)) + if (!bitmap || !test_bit(offset, bitmap->bitmap)) goto err; /* update bitmap and remove it if empty */ -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 4/9 V2] idr: fix idr_replace()'s returned error code 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan ` (2 preceding siblings ...) 2014-04-19 11:38 ` [PATCH 3/9 V2] idr: fix NULL pointer dereference when ida_remove(unallocated_id) Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan ` (4 subsequent siblings) 8 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger When the smaller id is not found, idr_replace() returns -ENOENT. But when the id is bigger enough, idr_replace() returns -EINVAL, actually there is no difference between these two kinds of ids. These are all unallocated id, the return values of the idr_replace() for these ids should be the same: -ENOENT. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> --- lib/idr.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 36ff732..e79e051 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -814,10 +814,10 @@ void *idr_replace(struct idr *idp, void *ptr, int id) p = idp->top; if (!p) - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOENT); if (id > idr_max(p->layer + 1)) - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOENT); n = p->layer * IDR_BITS; while ((n > 0) && p) { -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid. 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan ` (3 preceding siblings ...) 2014-04-19 11:38 ` [PATCH 4/9 V2] idr: fix idr_replace()'s returned error code Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 13:07 ` Tejun Heo 2014-04-19 11:38 ` [PATCH 6/9 V2] idr: avoid ping-pong Lai Jiangshan ` (3 subsequent siblings) 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger When the arguments passed by the caller are invalid, WARN_ON_ONCE() is proper than BUG_ON() which may crash the kernel. The invalid-checking for ida_simple_remove() is moved into ida_remove(). idr_remove() also adds this WARN_ON_ONCE(). And when "end < start" in ida_simple_get(), it returns -ENOSPC as ida_alloc() does. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index e79e051..317fd35 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -559,7 +559,7 @@ void idr_remove(struct idr *idp, int id) struct idr_layer *p; struct idr_layer *to_free; - if (id < 0) + if (WARN_ON_ONCE(id < 0)) return; if (id > idr_max(idp->layers)) { @@ -1030,6 +1030,9 @@ void ida_remove(struct ida *ida, int id) int n; struct ida_bitmap *bitmap; + if (WARN_ON_ONCE(id < 0)) + return; + if (idr_id > idr_max(ida->idr.layers)) goto err; @@ -1096,13 +1099,14 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, unsigned int max; unsigned long flags; - BUG_ON((int)start < 0); - BUG_ON((int)end < 0); + if (WARN_ON_ONCE(((int)start < 0) || ((int)end < 0))) + return -EINVAL; if (end == 0) max = 0x80000000; else { - BUG_ON(end < start); + if (WARN_ON_ONCE(end < start)) + return -ENOSPC; max = end - 1; } @@ -1138,7 +1142,6 @@ void ida_simple_remove(struct ida *ida, unsigned int id) { unsigned long flags; - BUG_ON((int)id < 0); spin_lock_irqsave(&simple_ida_lock, flags); ida_remove(ida, id); spin_unlock_irqrestore(&simple_ida_lock, flags); -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid. 2014-04-19 11:38 ` [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan @ 2014-04-19 13:07 ` Tejun Heo 2014-04-19 14:04 ` Lai Jiangshan 0 siblings, 1 reply; 38+ messages in thread From: Tejun Heo @ 2014-04-19 13:07 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Sat, Apr 19, 2014 at 07:38:12PM +0800, Lai Jiangshan wrote: > @@ -559,7 +559,7 @@ void idr_remove(struct idr *idp, int id) > struct idr_layer *p; > struct idr_layer *to_free; > > - if (id < 0) > + if (WARN_ON_ONCE(id < 0)) > return; ISTR callers which call in with error value, but yeah weeding them out could be a good idea. Shouldn't it be idr_remove_warning() though? > @@ -1030,6 +1030,9 @@ void ida_remove(struct ida *ida, int id) > int n; > struct ida_bitmap *bitmap; > > + if (WARN_ON_ONCE(id < 0)) > + return; Why not jump to err? > + > if (idr_id > idr_max(ida->idr.layers)) > goto err; > > @@ -1096,13 +1099,14 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, > unsigned int max; > unsigned long flags; > > - BUG_ON((int)start < 0); > - BUG_ON((int)end < 0); > + if (WARN_ON_ONCE(((int)start < 0) || ((int)end < 0))) > + return -EINVAL; > > if (end == 0) > max = 0x80000000; > else { > - BUG_ON(end < start); > + if (WARN_ON_ONCE(end < start)) > + return -ENOSPC; -EINVAL Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid. 2014-04-19 13:07 ` Tejun Heo @ 2014-04-19 14:04 ` Lai Jiangshan 2014-04-19 23:47 ` Tejun Heo 0 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 14:04 UTC (permalink / raw) To: Tejun Heo Cc: LKML, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Sat, Apr 19, 2014 at 9:07 PM, Tejun Heo <tj@kernel.org> wrote: > On Sat, Apr 19, 2014 at 07:38:12PM +0800, Lai Jiangshan wrote: >> @@ -559,7 +559,7 @@ void idr_remove(struct idr *idp, int id) >> struct idr_layer *p; >> struct idr_layer *to_free; >> >> - if (id < 0) >> + if (WARN_ON_ONCE(id < 0)) >> return; > > ISTR callers which call in with error value, but yeah weeding them out > could be a good idea. Shouldn't it be idr_remove_warning() though? WARN_ON_ONCE() for invalid id (negative id). idr_remove_warning() for unallocated id. > >> @@ -1030,6 +1030,9 @@ void ida_remove(struct ida *ida, int id) >> int n; >> struct ida_bitmap *bitmap; >> >> + if (WARN_ON_ONCE(id < 0)) >> + return; > > Why not jump to err? WARN_ON_ONCE() for invalid id (negative id). "goto err" for unallocated id. > >> + >> if (idr_id > idr_max(ida->idr.layers)) >> goto err; >> >> @@ -1096,13 +1099,14 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, >> unsigned int max; >> unsigned long flags; >> >> - BUG_ON((int)start < 0); >> - BUG_ON((int)end < 0); >> + if (WARN_ON_ONCE(((int)start < 0) || ((int)end < 0))) >> + return -EINVAL; >> >> if (end == 0) >> max = 0x80000000; >> else { >> - BUG_ON(end < start); >> + if (WARN_ON_ONCE(end < start)) >> + return -ENOSPC; > > -EINVAL In my V1 patch, it returns -EINVAL. The V2 changelog explain this change: make the returned value as the same as idr_alloc(). ### It is important for cyclic allocation (idr_alloc()). int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask) { int id; id = idr_alloc(idr, ptr, max(start, idr->cur), end, gfp_mask); if (id == -ENOSPC) id = idr_alloc(idr, ptr, start, end, gfp_mask); if (likely(id >= 0)) idr->cur = id + 1; return id; } idr->cur can equals to @end. idr_alloc() should return -ENOSPC for next idr_alloc(). > > Thanks. > > -- > tejun > -- > 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/ ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid. 2014-04-19 14:04 ` Lai Jiangshan @ 2014-04-19 23:47 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-19 23:47 UTC (permalink / raw) To: Lai Jiangshan Cc: LKML, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger Hello, On Sat, Apr 19, 2014 at 10:04:06PM +0800, Lai Jiangshan wrote: > On Sat, Apr 19, 2014 at 9:07 PM, Tejun Heo <tj@kernel.org> wrote: > WARN_ON_ONCE() for invalid id (negative id). > idr_remove_warning() for unallocated id. I don't know. Seem like an unnecessary distinction. > >> @@ -1030,6 +1030,9 @@ void ida_remove(struct ida *ida, int id) > >> int n; > >> struct ida_bitmap *bitmap; > >> > >> + if (WARN_ON_ONCE(id < 0)) > >> + return; > > > > Why not jump to err? > > WARN_ON_ONCE() for invalid id (negative id). > "goto err" for unallocated id. Ditto. Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 6/9 V2] idr: avoid ping-pong 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan ` (4 preceding siblings ...) 2014-04-19 11:38 ` [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 7/9 V2] idr: don't need to shink the free list when idr_remove() Lai Jiangshan ` (2 subsequent siblings) 8 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger The ida callers always calls ida_pre_get() before ida_get_new*(). ida_pre_get() will always do layer allocation, which means the layer removal in ida_get_new*() is helpless. ida_get_new*() frees and the ida_pre_get() for the next ida_get_new*() allocates. It causes an unneeded ping-pong. The aim "Throw away extra resources one by one" can't be achieved. This speculative layer removal in ida_get_new*() can't result expected optimization. So we remove the unneeded layer removal in ida_get_new*(). Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 11 ----------- 1 files changed, 0 insertions(+), 11 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 317fd35..25fe476 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -1001,17 +1001,6 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) *p_id = id; - /* Each leaf node can handle nearly a thousand slots and the - * whole idea of ida is to have small memory foot print. - * Throw away extra resources one by one after each successful - * allocation. - */ - if (ida->idr.id_free_cnt || ida->free_bitmap) { - struct idr_layer *p = get_from_free_list(&ida->idr); - if (p) - kmem_cache_free(idr_layer_cache, p); - } - return 0; } EXPORT_SYMBOL(ida_get_new_above); -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 7/9 V2] idr: don't need to shink the free list when idr_remove() 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan ` (5 preceding siblings ...) 2014-04-19 11:38 ` [PATCH 6/9 V2] idr: avoid ping-pong Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 8/9 V2] idr: reduce the unneeded check in free_layer() Lai Jiangshan 2014-04-19 11:38 ` [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch Lai Jiangshan 8 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger After idr subsystem is changed to RCU-awared, the free layer will not go to the free list. The free list will not be filled up when idr_remove(). So we don't need to shink it too. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> --- lib/idr.c | 16 ---------------- 1 files changed, 0 insertions(+), 16 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 25fe476..4a11c5d 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -18,12 +18,6 @@ * pointer or what ever, we treat it as a (void *). You can pass this * id to a user for him to pass back at a later time. You then pass * that id to this code and it returns your pointer. - - * You can release ids at any time. When all ids are released, most of - * the memory is returned (we keep MAX_IDR_FREE) in a local pool so we - * don't need to go to the memory "store" during an id allocate, just - * so you don't need to be too concerned about locking and conflicts - * with the slab allocator. */ #ifndef TEST // to test in user space... @@ -584,16 +578,6 @@ void idr_remove(struct idr *idp, int id) bitmap_clear(to_free->bitmap, 0, IDR_SIZE); free_layer(idp, to_free); } - while (idp->id_free_cnt >= MAX_IDR_FREE) { - p = get_from_free_list(idp); - /* - * Note: we don't call the rcu callback here, since the only - * layers that fall into the freelist are those that have been - * preallocated. - */ - kmem_cache_free(idr_layer_cache, p); - } - return; } EXPORT_SYMBOL(idr_remove); -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 8/9 V2] idr: reduce the unneeded check in free_layer() 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan ` (6 preceding siblings ...) 2014-04-19 11:38 ` [PATCH 7/9 V2] idr: don't need to shink the free list when idr_remove() Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 11:38 ` [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch Lai Jiangshan 8 siblings, 0 replies; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger If "idr->hint == p" is true, it also implies "idr->hint" is true(not NULL). Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> --- lib/idr.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 4a11c5d..e3c1da0 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -145,7 +145,7 @@ static void idr_layer_rcu_free(struct rcu_head *head) static inline void free_layer(struct idr *idr, struct idr_layer *p) { - if (idr->hint && idr->hint == p) + if (idr->hint == p) RCU_INIT_POINTER(idr->hint, NULL); call_rcu(&p->rcu_head, idr_layer_rcu_free); } -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan ` (7 preceding siblings ...) 2014-04-19 11:38 ` [PATCH 8/9 V2] idr: reduce the unneeded check in free_layer() Lai Jiangshan @ 2014-04-19 11:38 ` Lai Jiangshan 2014-04-19 23:51 ` Tejun Heo 8 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-19 11:38 UTC (permalink / raw) To: Tejun Heo, linux-kernel Cc: Lai Jiangshan, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger "#ifndef TEST" can't work for user space test now, just remove it. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- lib/idr.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index e3c1da0..d77cdca 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -20,11 +20,9 @@ * that id to this code and it returns your pointer. */ -#ifndef TEST // to test in user space... #include <linux/slab.h> #include <linux/init.h> #include <linux/export.h> -#endif #include <linux/err.h> #include <linux/string.h> #include <linux/idr.h> -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch 2014-04-19 11:38 ` [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch Lai Jiangshan @ 2014-04-19 23:51 ` Tejun Heo 2014-04-20 3:56 ` Lai Jiangshan 0 siblings, 1 reply; 38+ messages in thread From: Tejun Heo @ 2014-04-19 23:51 UTC (permalink / raw) To: Lai Jiangshan Cc: linux-kernel, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger $SUBJ: idr: remove useless #ifndef TEST On Sat, Apr 19, 2014 at 07:38:16PM +0800, Lai Jiangshan wrote: > "#ifndef TEST" can't work for user space test now, just remove it. > > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Tejun Heo <tj@kernel.org> Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch 2014-04-19 23:51 ` Tejun Heo @ 2014-04-20 3:56 ` Lai Jiangshan 2014-04-20 11:29 ` Tejun Heo 0 siblings, 1 reply; 38+ messages in thread From: Lai Jiangshan @ 2014-04-20 3:56 UTC (permalink / raw) To: Tejun Heo Cc: LKML, Andrew Morton, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger On Sun, Apr 20, 2014 at 7:51 AM, Tejun Heo <tj@kernel.org> wrote: > $SUBJ: idr: remove useless #ifndef TEST > > On Sat, Apr 19, 2014 at 07:38:16PM +0800, Lai Jiangshan wrote: >> "#ifndef TEST" can't work for user space test now, just remove it. >> >> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> > > Acked-by: Tejun Heo <tj@kernel.org> Hi, Tejun Will you accept the acked patches into your tj/misc.git tree? (Or somebody else accepts the idr patches?). 5/9 will be sent later (in other patchset) 6/8 will be dropped. Thanks, Lai > > Thanks. > > -- > tejun > -- > 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/ ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch 2014-04-20 3:56 ` Lai Jiangshan @ 2014-04-20 11:29 ` Tejun Heo 0 siblings, 0 replies; 38+ messages in thread From: Tejun Heo @ 2014-04-20 11:29 UTC (permalink / raw) To: Lai Jiangshan, Andrew Morton Cc: LKML, Jean Delvare, Monam Agarwal, Jeff Layton, Andreas Gruenbacher, Stephen Hemminger Hello, On Sun, Apr 20, 2014 at 11:56:02AM +0800, Lai Jiangshan wrote: > On Sun, Apr 20, 2014 at 7:51 AM, Tejun Heo <tj@kernel.org> wrote: > > $SUBJ: idr: remove useless #ifndef TEST > > > > On Sat, Apr 19, 2014 at 07:38:16PM +0800, Lai Jiangshan wrote: > >> "#ifndef TEST" can't work for user space test now, just remove it. > >> > >> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> > > > > Acked-by: Tejun Heo <tj@kernel.org> > > Hi, Tejun > > Will you accept the acked patches into your tj/misc.git tree? > (Or somebody else accepts the idr patches?). I can route them through misc or Andrew can take them through -mm, which probably would be better. > 5/9 will be sent later (in other patchset) > 6/8 will be dropped. Andrew, can you please take the acked patches? Thanks. -- tejun ^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2014-04-20 11:29 UTC | newest] Thread overview: 38+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-04-18 12:49 [PATCH 0/8] idr: fix & cleanup Lai Jiangshan 2014-04-18 12:49 ` [PATCH 1/8] idr: fix overflow bug for the max-high layer Lai Jiangshan 2014-04-18 16:29 ` Tejun Heo 2014-04-18 17:08 ` Lai Jiangshan 2014-04-18 17:10 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 2/8] idr: fix unexpected id-removal when idr_remove(unallocated_id) Lai Jiangshan 2014-04-18 16:57 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 3/8] idr: fix NULL pointer dereference when ida_remove(unallocated_id) Lai Jiangshan 2014-04-18 17:09 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 4/8] idr: fix idr_replace()'s returned error code Lai Jiangshan 2014-04-18 17:12 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 5/8] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan 2014-04-18 17:14 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 6/8] idr: avoid ping-pong Lai Jiangshan 2014-04-18 17:17 ` Tejun Heo 2014-04-19 10:43 ` Lai Jiangshan 2014-04-19 13:01 ` Tejun Heo 2014-04-19 14:23 ` Lai Jiangshan 2014-04-18 12:49 ` [PATCH 7/8] idr: don't need to shink the free list when idr_remove() Lai Jiangshan 2014-04-18 17:19 ` Tejun Heo 2014-04-18 12:49 ` [PATCH 8/8] idr: reduce the unneeded check in free_layer() Lai Jiangshan 2014-04-18 17:21 ` Tejun Heo 2014-04-19 11:38 ` [PATCH 0/9 V2] idr: fix & cleanup Lai Jiangshan 2014-04-19 11:38 ` [PATCH 1/9 V2] idr: fix overflow bug during maximum ID calculation at maximum height Lai Jiangshan 2014-04-19 11:38 ` [PATCH 2/9 V2] idr: fix unexpected ID-removal when idr_remove(unallocated_id) Lai Jiangshan 2014-04-19 11:38 ` [PATCH 3/9 V2] idr: fix NULL pointer dereference when ida_remove(unallocated_id) Lai Jiangshan 2014-04-19 11:38 ` [PATCH 4/9 V2] idr: fix idr_replace()'s returned error code Lai Jiangshan 2014-04-19 11:38 ` [PATCH 5/9 V2] idr: covert BUG_ON() to WARN_ON_ONCE() if the argument is invalid Lai Jiangshan 2014-04-19 13:07 ` Tejun Heo 2014-04-19 14:04 ` Lai Jiangshan 2014-04-19 23:47 ` Tejun Heo 2014-04-19 11:38 ` [PATCH 6/9 V2] idr: avoid ping-pong Lai Jiangshan 2014-04-19 11:38 ` [PATCH 7/9 V2] idr: don't need to shink the free list when idr_remove() Lai Jiangshan 2014-04-19 11:38 ` [PATCH 8/9 V2] idr: reduce the unneeded check in free_layer() Lai Jiangshan 2014-04-19 11:38 ` [PATCH 9/9 V2] idr: remove useless C-PreProcessor branch Lai Jiangshan 2014-04-19 23:51 ` Tejun Heo 2014-04-20 3:56 ` Lai Jiangshan 2014-04-20 11:29 ` Tejun Heo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox