Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933970AbcLHB34 (ORCPT ); Wed, 7 Dec 2016 20:29:56 -0500 Received: from mail-wj0-f179.google.com ([209.85.210.179]:33897 "EHLO mail-wj0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932372AbcLHB3x (ORCPT ); Wed, 7 Dec 2016 20:29:53 -0500 From: Rasmus Villemoes To: Tejun Heo , Andrew Morton Cc: linux-kernel@vger.kernel.org, Lai Jiangshan , Jens Axboe , Greg Kroah-Hartman , Rasmus Villemoes Subject: [RFC 08/10] lib/tida.c: introduce tida_get_above Date: Thu, 8 Dec 2016 02:23:03 +0100 Message-Id: <1481160187-9652-9-git-send-email-linux@rasmusvillemoes.dk> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1481160187-9652-1-git-send-email-linux@rasmusvillemoes.dk> References: <1481160187-9652-1-git-send-email-linux@rasmusvillemoes.dk> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2690 Lines: 96 Some potential users want to impose a minimum on the returned id. Extend tida_get to accept a start parameter, renaming it to tida_get_above, and make tida_get a trivial wrapper. Signed-off-by: Rasmus Villemoes --- include/linux/tida.h | 8 +++++++- lib/tida.c | 22 +++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/include/linux/tida.h b/include/linux/tida.h index 9aa3ad96a632..a76fe01bee0b 100644 --- a/include/linux/tida.h +++ b/include/linux/tida.h @@ -19,8 +19,14 @@ struct tida { void tida_init(struct tida *tida); void tida_destroy(struct tida *tida); -int tida_get(struct tida *tida, gfp_t gfp); +int tida_get_above(struct tida *tida, int start, gfp_t gfp); void tida_put(struct tida *tida, int id); +static inline int +tida_get(struct tida *tida, gfp_t gfp) +{ + return tida_get_above(tida, 0, gfp); +} + #endif /* __LINUX_TIDA_H__ */ diff --git a/lib/tida.c b/lib/tida.c index 1ea0deb6fa64..0d43b207325a 100644 --- a/lib/tida.c +++ b/lib/tida.c @@ -23,16 +23,15 @@ */ static int -tida_expand(struct tida *tida, gfp_t gfp, unsigned long *flags) +tida_expand(struct tida *tida, gfp_t gfp, unsigned long *flags, unsigned long minalloc) __releases(tida->lock) __acquires(tida->lock) { unsigned long newalloc, oldalloc = tida->alloc; unsigned long *bits; - newalloc = oldalloc ? 2 * oldalloc : BITS_PER_LONG; - spin_unlock_irqrestore(&tida->lock, *flags); + newalloc = max(2*oldalloc, round_up(minalloc, BITS_PER_LONG)); bits = kcalloc(BITS_TO_LONGS(newalloc), sizeof(*bits), gfp); spin_lock_irqsave(&tida->lock, *flags); @@ -50,29 +49,34 @@ tida_expand(struct tida *tida, gfp_t gfp, unsigned long *flags) } int -tida_get(struct tida *tida, gfp_t gfp) +tida_get_above(struct tida *tida, int start, gfp_t gfp) { unsigned long flags; - int ret; + int ret, from; + + if (WARN_ON_ONCE(start < 0)) + return -EINVAL; spin_lock_irqsave(&tida->lock, flags); while (1) { /* find_next_zero_bit is fine with a NULL bitmap as long as size is 0 */ - ret = find_next_zero_bit(tida->bits, tida->alloc, tida->hint); + from = max(start, tida->hint); + ret = find_next_zero_bit(tida->bits, tida->alloc, from); if (ret < tida->alloc) break; - ret = tida_expand(tida, gfp, &flags); + ret = tida_expand(tida, gfp, &flags, from + 1); if (ret < 0) goto out; } __set_bit(ret, tida->bits); - tida->hint = ret+1; + if (start <= tida->hint) + tida->hint = ret + 1; out: spin_unlock_irqrestore(&tida->lock, flags); return ret; } -EXPORT_SYMBOL_GPL(tida_get); +EXPORT_SYMBOL_GPL(tida_get_above); void tida_put(struct tida *tida, int id) -- 2.1.4