From patchwork Fri Jun 23 09:10:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Christie X-Patchwork-Id: 9806019 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A99A560349 for ; Fri, 23 Jun 2017 09:10:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9AC7828583 for ; Fri, 23 Jun 2017 09:10:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8F58028630; Fri, 23 Jun 2017 09:10:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F22282861F for ; Fri, 23 Jun 2017 09:10:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754382AbdFWJKY (ORCPT ); Fri, 23 Jun 2017 05:10:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47520 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754343AbdFWJKV (ORCPT ); Fri, 23 Jun 2017 05:10:21 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D09417CE09; Fri, 23 Jun 2017 09:10:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com D09417CE09 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=mchristi@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com D09417CE09 Received: from rh2.redhat.com (ovpn-120-27.rdu2.redhat.com [10.10.120.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2DEE817F58; Fri, 23 Jun 2017 09:10:20 +0000 (UTC) From: Mike Christie To: bart.vanassche@wdc.com, target-devel@vger.kernel.org, nab@linux-iscsi.org Cc: Mike Christie Subject: [RFC PATCH 1/4] ida: add simple cyclic allocator support Date: Fri, 23 Jun 2017 04:10:14 -0500 Message-Id: <1498209017-25110-2-git-send-email-mchristi@redhat.com> In-Reply-To: <1498209017-25110-1-git-send-email-mchristi@redhat.com> References: <1498209017-25110-1-git-send-email-mchristi@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 23 Jun 2017 09:10:21 +0000 (UTC) Sender: target-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: target-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch modifies ida_get_simple to support cyclic allocation similar to idr_alloc_cyclic. It will be used in the next target layer patches to allocate IDs for info that is passed to apps that were relying on the info's IDs to change after device deletion then readdition sequences. Signed-off-by: Mike Christie --- include/linux/idr.h | 3 ++ lib/idr.c | 79 +++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/include/linux/idr.h b/include/linux/idr.h index bf70b3e..cabf9fb 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -176,6 +176,7 @@ DECLARE_PER_CPU(struct ida_bitmap *, ida_bitmap); struct ida { struct radix_tree_root ida_rt; + unsigned int ida_next; }; #define IDA_INIT { \ @@ -188,6 +189,8 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id); void ida_remove(struct ida *ida, int id); void ida_destroy(struct ida *ida); +int ida_simple_get_cyclic(struct ida *ida, unsigned int start, unsigned int end, + gfp_t gfp_mask); 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); diff --git a/lib/idr.c b/lib/idr.c index b13682b..bee57a6 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -407,25 +407,10 @@ void ida_destroy(struct ida *ida) } EXPORT_SYMBOL(ida_destroy); -/** - * ida_simple_get - 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. - * - * 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(struct ida *ida, unsigned int start, unsigned int end, - gfp_t gfp_mask) +static int __ida_simple_get(struct ida *ida, unsigned int start, + unsigned int end, bool cyclic, gfp_t gfp_mask) { - int ret, id; + int ret, id, curr; unsigned int max; unsigned long flags; @@ -439,18 +424,28 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, max = end - 1; } + curr = start; again: if (!ida_pre_get(ida, gfp_mask)) return -ENOMEM; spin_lock_irqsave(&simple_ida_lock, flags); - ret = ida_get_new_above(ida, start, &id); + if (cyclic && ida->ida_next > curr) + curr = ida->ida_next; + + ret = ida_get_new_above(ida, curr, &id); if (!ret) { if (id > max) { ida_remove(ida, id); - ret = -ENOSPC; + if (cyclic && ida->ida_next > start) { + curr = ida->ida_next = start; + ret = -EAGAIN; + } else { + ret = -ENOSPC; + } } else { ret = id; + ida->ida_next = id + 1U; } } spin_unlock_irqrestore(&simple_ida_lock, flags); @@ -460,9 +455,53 @@ int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, return ret; } + +/** + * ida_simple_get - 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. + * + * 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(struct ida *ida, unsigned int start, unsigned int end, + gfp_t gfp_mask) +{ + return __ida_simple_get(ida, start, end, false, gfp_mask); +} 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 larger than the last ID allocated and less than @end. + * If @end is reached, it will attempt to allocate the smallest ID that is + * larger or equal to @start. + * + * If there are no available IDs returns -ENOSPC. + * On memory allocation failure, returns -ENOMEM. + * + * 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) +{ + return __ida_simple_get(ida, start, end, true, gfp_mask); +} +EXPORT_SYMBOL(ida_simple_get_cyclic); + +/** * ida_simple_remove - remove an allocated id. * @ida: the (initialized) ida. * @id: the id returned by ida_simple_get.