Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2021947imm; Thu, 7 Jun 2018 04:16:25 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLQjZpQHlPFQqLkMe07YajJVoekSOO7JM3CPUrrfgM01bNgAJ0oOAUHkqygDlYs01yyw9Qc X-Received: by 2002:a62:7db:: with SMTP id 88-v6mr1408290pfh.178.1528370185662; Thu, 07 Jun 2018 04:16:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528370185; cv=none; d=google.com; s=arc-20160816; b=K6VKD6nnBaKinD9falsqaUDB8/eEtq2v6SZxkXm3ADS1zFBBKnUHNeUhTEcbkk+Y6y k+v0cTXHrJw8jEzDN3yO1ojNxv4jGKqKx0PH8+jybrx9qmpI0y1nZ3MT5qwzdCSnujwR 2CliDM1WqaU9nC4v//H+mCw8riwsD02pghmxjs9UpDvQAEolRE3y8dv1Wl5uPTOLjO0I J1Hv0yAjP2TvrDjk6PRwAbwPzTApqDat9iBJTeUnHpNRAM5c2ZfQXoV2eqcVaJpJh/Mh Nrn2n+PA7JNFQB6bB+ID5sdKobgJ/SqJxUs8mzswZ5J8nID5t2Ej+N/iezbrz1sxYEbm MWqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:arc-authentication-results; bh=FoJdPP4hYaRyzVJNDR1Gu3aOnDLTIFrZO3sIViiJqB0=; b=fBTTMoUeV/vvmX2zU7xqVzCPxjO0Ve176W0JXtDtKqCl75ynxaDSZeOizXMdFc3Fa3 hKFe5mhUNXLfyV3plVLLqkmdPC3rt9qHAVdbQjEWA+MEqRj7qta95vwJzTghcU8Omfpx qaLpoSsmAo0ccAIl//FSwMJP2wfbNa8wcBl/zqa7I0L+/7vDjjb5SkmGdbbI/jnxCuzZ Rq9Xil4pEisNNkfqayGckD2vUMnbQw0J4NmI3V5IsoHpFPtkncwCYQgNFqXui/dekRto xNDK8D4Q0+s2DvXG7JZ0d4p7nDfWQvTgpaHLrO4W4o5vtYVWZm5/p+rC+uEdYrEcj9ej 1HGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2017-10-26 header.b=L8n/hkJH; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 35-v6si20189828pla.543.2018.06.07.04.16.10; Thu, 07 Jun 2018 04:16:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2017-10-26 header.b=L8n/hkJH; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932066AbeFGLPk (ORCPT + 99 others); Thu, 7 Jun 2018 07:15:40 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:50772 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753004AbeFGLPh (ORCPT ); Thu, 7 Jun 2018 07:15:37 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w57BBiPq164357; Thu, 7 Jun 2018 11:15:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2017-10-26; bh=FoJdPP4hYaRyzVJNDR1Gu3aOnDLTIFrZO3sIViiJqB0=; b=L8n/hkJH2qg1F/mGlQZmViLTCjSv3S/AcqndSeJ48xpZ8CAz1tumWxb0k1hpD0k0K1Gh Lwtg+x/11MjeVAcwRL00W3qvP3NtMUdAyf+Ma17HCC2+T1KH3z/T0UW8tsx10mD4PKnt yuW0oLhm0Rdn01jmLAyhrOK79t1uCKZkZMpD7T3Wcnf/0WMym3WTw79HFFU+datr7ux3 XKRh4I+PomHddYAu+g4pxR1YAEBd7iT1oBki4UKVPCYwx76RImkaIkRL03eKAn4NJ57d lESJCrXdfXi2Vg/9OK0u1ZP+0O+Ja58ExDtW9D17iKjIcw4Bcl1sXEe4XLv7Y6qp+Pur dQ== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp2130.oracle.com with ESMTP id 2jbvypgh6n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 07 Jun 2018 11:15:10 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w57BFAsx002683 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 7 Jun 2018 11:15:10 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id w57BF8MS014932; Thu, 7 Jun 2018 11:15:08 GMT Received: from lab02.no.oracle.com (/10.172.144.56) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 07 Jun 2018 04:15:08 -0700 From: Hans Westgaard Ry To: Doug Ledford , Jason Gunthorpe , Hakon Bugge , Parav Pandit , Jack Morgenstein , Pravin Shedge , Matthew Wilcox , Andrew Morton , Jeff Layton , Wei Wang , Chris Mi , Eric Biggers , Rasmus Villemoes , Mel Gorman , linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/2] idr: Add ida_simple_get_cyclic Date: Thu, 7 Jun 2018 13:14:34 +0200 Message-Id: <20180607111435.17538-2-hans.westgaard.ry@oracle.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180607111435.17538-1-hans.westgaard.ry@oracle.com> References: <20180529073808.27735-1-hans.westgaard.ry@oracle.com> <20180607111435.17538-1-hans.westgaard.ry@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8916 signatures=668702 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=2 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=966 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1805220000 definitions=main-1806070132 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Hans Westgaard Ry --- include/linux/idr.h | 8 +++++-- lib/idr.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/include/linux/idr.h b/include/linux/idr.h index e856f4e0ab35..f151ce89124a 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -218,10 +218,12 @@ DECLARE_PER_CPU(struct ida_bitmap *, ida_bitmap); struct ida { struct radix_tree_root ida_rt; + unsigned int ida_next; }; -#define IDA_INIT(name) { \ - .ida_rt = RADIX_TREE_INIT(name, IDR_RT_MARKER | GFP_NOWAIT), \ +#define IDA_INIT(name) { \ + .ida_rt = RADIX_TREE_INIT(name, IDR_RT_MARKER | GFP_NOWAIT), \ + .ida_next = 0, \ } #define DEFINE_IDA(name) struct ida name = IDA_INIT(name) @@ -232,6 +234,8 @@ void ida_destroy(struct ida *ida); int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, gfp_t gfp_mask); +int ida_simple_get_cyclic(struct ida *ida, unsigned int start, unsigned int end, + gfp_t gfp_mask); void ida_simple_remove(struct ida *ida, unsigned int id); static inline void ida_init(struct ida *ida) diff --git a/lib/idr.c b/lib/idr.c index 823b813f08f8..3374c3fa4027 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -599,6 +599,72 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, return ret; } EXPORT_SYMBOL(ida_simple_get); +/** + * ida_simple_get_cyclic - get a new id. + * @ida: the (initialized) ida. + * @start: the minimum id (inclusive, < 0x8000000) + * @end: the maximum id (exclusive, < 0x8000000 or 0) + * @gfp_mask: memory allocation flags + * + * Allocates an id in the range start <= id < end, or returns -ENOSPC. + * On memory allocation failure, returns -ENOMEM. + * The search for an unused id will start at the last id allocated and will + * wrap around to @start if no free ids are found before reaching @end. + * + * Compared to ida_get_new_above() this function does its own locking, and + * should be used unless there are special requirements. + * + * Use ida_simple_remove() to get rid of an id. + */ +int ida_simple_get_cyclic(struct ida *ida, unsigned int start, unsigned int end, + gfp_t gfp_mask) +{ + int ret, id, next; + unsigned int max; + unsigned long flags; + + WARN_ON((int)start < 0); + WARN_ON((int)end < 0); + + if (end == 0) { + max = 0x80000000; + } else { + WARN_ON(end < start); + max = end - 1; + } + +again: + if (!ida_pre_get(ida, gfp_mask)) + return -ENOMEM; + + spin_lock_irqsave(&simple_ida_lock, flags); + next = ida->ida_next; + if (next < start || next >= end) + next = start; + + ret = ida_get_new_above(ida, next, &id); + if (likely(!ret)) { + if (unlikely(id >= max)) { + ida_remove(ida, id); + if (next == start) { + ret = -ENOSPC; + } else { + ida->ida_next = start; + spin_unlock_irqrestore(&simple_ida_lock, flags); + goto again; + } + } else { + ida->ida_next = id + 1; + ret = id; + } + } + spin_unlock_irqrestore(&simple_ida_lock, flags); + + if (unlikely(ret == -EAGAIN)) + goto again; + return ret; +} +EXPORT_SYMBOL(ida_simple_get_cyclic); /** * ida_simple_remove - remove an allocated id. -- 2.14.3