Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp189678imu; Thu, 6 Dec 2018 22:33:23 -0800 (PST) X-Google-Smtp-Source: AFSGD/VIczbsI85wWh8LMo1ZSKelFViFrYm4fErgfxDsLh0xJPCikRnMJZy174LlbkkZWa+xfysg X-Received: by 2002:a63:3204:: with SMTP id y4mr893919pgy.41.1544164403124; Thu, 06 Dec 2018 22:33:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544164403; cv=none; d=google.com; s=arc-20160816; b=QEpMCNtUrtYzpk660aRmdB3c+lHr93/QNeH1AEGU18WRbGQ5b4X9fOCJdIH8e+UoJ9 KaYPXrEmzPt93Mpbi8eZv4eWMIDDC/fgU6vgHkabeaDw+aWhOWfrDZp6fonzOvfnUB2n iH867vY6xpEjcv3A9yiKZSrpYJBJA9HIhd3kbgA6nklyjNPavqK172aD+GzAB0uCkDT6 +A1Bi4DHPFfjkEO0yTO676FHAaoN/IbOYSH/CPwMu6fvHOWmI8ptnRd6Rmu363m6qwv4 +uFC6RwIPkILG3kcYdXOtLlKsv2KcpW1+qJDAbigzdUbGQ34FjzEL+vvloGKoLoN7ICa 0PoA== 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:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=7MfUEQQkpsvuhuLJsGgSUDCmSQkbYrqMmWgv/EsP3fo=; b=wGC7skJ18mal6RQuAcnOZt5IgEim23LjY55TR1IK6ZPD6YNyrIDxwyukMH/DrxTv1M sXThD6rb7bCeEZWYVmUhZ4X0Il89s13cG1YBEfEgaxHgqMG8i6BcCAZLhBDVLL/+I+UX l8ZNAMNxG/wFZDYjrbzZdFs8dc8OQ+2uBraZ+jCYHln0jA3Sd1Cvv2pv77l04FXNqQXh 1Bad6sfZrtl8Mlb0P2j8SOGi6CUSPfXaCI+PiwRGOodcT2Z2PKRn6Ni5Vs961S1oiohH Z4J9Ez0NARvH+ZnhEbMNbHVwRg3aE8OObajcuLVnkAGkahkKsCjMSHJMYIWHHIyfX8WG fljA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=PXGgMFcU; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l4si2107703pgr.346.2018.12.06.22.33.06; Thu, 06 Dec 2018 22:33:23 -0800 (PST) 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=@gmail.com header.s=20161025 header.b=PXGgMFcU; 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=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726111AbeLGGbB (ORCPT + 99 others); Fri, 7 Dec 2018 01:31:01 -0500 Received: from mail-pf1-f196.google.com ([209.85.210.196]:35348 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725948AbeLGGbB (ORCPT ); Fri, 7 Dec 2018 01:31:01 -0500 Received: by mail-pf1-f196.google.com with SMTP id z9so1450211pfi.2; Thu, 06 Dec 2018 22:31:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=7MfUEQQkpsvuhuLJsGgSUDCmSQkbYrqMmWgv/EsP3fo=; b=PXGgMFcUw1JOXrkayVkXHCuO5iRRzyw6IyZ5NZvlfVGIUhWArFEagsY7lLgmpfta/F PbanvNRZaiOJN7FbpXO4afRzVLGob3YO6WUiIjvNEBNnv2O0NQs7NQF4DpK6OwWz6EmT BuF35RIvowKq23f5S9XXJJdavt+Qu/jMdS776xMpKqrtMX4zX135xDPaHP5oQ1TiP/wA sIu4LQqCC8UQYobTW7iqoz8Iwa89AJlIeyj0/miAP9EAdviYVH/s5syGE2cvW3sC+G7v tF9bZ5ZZn/SQYtwk4INh2IsYjKaryZ1975yfSNKwUQaWpXgl/a3a0cqr2qIyWmoAjqgp 2stA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=7MfUEQQkpsvuhuLJsGgSUDCmSQkbYrqMmWgv/EsP3fo=; b=W81O2ouly4/J1Q5/rYF34bW1wVS9E8oUTWkQ0Wjf0qsxfUT25rKJ9YK61IWE7/h9lf plLfP21qB2VI0vCQSGYkWbvrrI6ZKH6TLPYIXsbVe+Eu4RN/Uv3wcmCi2uK6nBixtWIu hP0d6JBGkhUdsXk5Dam7Dxby7/Ob4AQrY9D+/orTp7T0B4OujKl1EfJkM21FzmeitECf 1o777QSRGRJyt2JAg9UJdOgChv6aKjYUfMoXA0xJTu7NsaaaXvuq42O1PWmoCgN9YDkG IswlU1G+eP5GuSnDCEwXFgjscI1tcxN5AHrB8QSWXB9WHTZHgEsEeIUIYS/oI13xAJgN uBug== X-Gm-Message-State: AA+aEWZ2PgmRirStVdq9ybXx2D/P/xDmX5TedtVMvUg54Dd5qE5LwdVo VysyNoqLgAuhuRsZ4MlaPE2vaQG4eEk= X-Received: by 2002:a62:cf84:: with SMTP id b126mr1054017pfg.98.1544164259934; Thu, 06 Dec 2018 22:30:59 -0800 (PST) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id 84sm4719553pfk.134.2018.12.06.22.30.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 06 Dec 2018 22:30:59 -0800 (PST) From: Xin Long To: linux-kernel@vger.kernel.org, network dev , linux-sctp@vger.kernel.org Cc: davem@davemloft.net, Marcelo Ricardo Leitner , Neil Horman , Dave Hansen , David Rientjes , Eric Paris , Konstantin Khorenko Subject: [PATCHv2 net 2/3] flex_array: support flex_array_resize Date: Fri, 7 Dec 2018 14:30:34 +0800 Message-Id: <9122685dd16d04613de02594325acf79b2d04a3d.1544163962.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This function can dynamically change total_nr_elements of a flex_array, and keep the old elements of the same memory. Returns 0 if it succeeds. Note that it won't do any memory allocation or shrinking for elements, which should be only done by flex_array_prealloc and flex_array_shrink. Suggested-by: Neil Horman Signed-off-by: Xin Long Acked-by: Neil Horman --- include/linux/flex_array.h | 11 +++++++++ lib/flex_array.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h index 29ad65f..19ff58d 100644 --- a/include/linux/flex_array.h +++ b/include/linux/flex_array.h @@ -130,6 +130,17 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr); */ int flex_array_shrink(struct flex_array *fa); +/** + * flex_array_resize() - Resize without the old elements memory changed + * @fa: array to resize + * @total: total number of elements that this would change to + * @flags: page allocation flags to use for base array + * + * Return: Returns 0 if it succeeds. + * + */ +int flex_array_resize(struct flex_array *fa, unsigned int total, gfp_t flags); + #define flex_array_put_ptr(fa, nr, src, gfp) \ flex_array_put(fa, nr, (void *)&(src), gfp) diff --git a/lib/flex_array.c b/lib/flex_array.c index 8c0b9b6..2f913e7 100644 --- a/lib/flex_array.c +++ b/lib/flex_array.c @@ -405,3 +405,61 @@ int flex_array_shrink(struct flex_array *fa) return ret; } EXPORT_SYMBOL(flex_array_shrink); + +/** + * flex_array_resize - resize without the old elements memory changed + * @fa: the flex array to resize + * @total: total number of elements that this would change to + * @flags: page allocation flags to use for base array + * + * This function can dynamically change total_nr_elements of a flex_array, + * and keep the old elements of the same memory. Returns 0 if it succeeds. + * Note that it won't do any memory allocation or shrinking for elements, + * which should be only done by flex_array_prealloc and flex_array_shrink. + * + * Locking must be provided by the caller. + */ +int flex_array_resize(struct flex_array *fa, unsigned int total, gfp_t flags) +{ + int nr; + + if (total > FLEX_ARRAY_NR_BASE_PTRS * fa->elems_per_part) + return -EINVAL; + + if (elements_fit_in_base(fa)) { + struct flex_array_part_p *part_p; + + nr = fa->total_nr_elements; + fa->total_nr_elements = total; + if (elements_fit_in_base(fa)) + return 0; + + part_p = kzalloc(sizeof(*part_p), flags); + if (!part_p) { + fa->total_nr_elements = nr; + return -ENOMEM; + } + + part_p->p_part[0] = (struct flex_array_part *)&fa->parts[0]; + fa->part_p = part_p; + } else { + struct flex_array_part *part; + + fa->total_nr_elements = total; + if (!elements_fit_in_base(fa)) + return 0; + + for (nr = 1; nr < FLEX_ARRAY_NR_BASE_PTRS; nr++) { + part = fa->parts[nr]; + if (part) { + fa->parts[nr] = NULL; + kfree(part); + } + } + + fa->part_p = (struct flex_array_part_p *)fa->parts[0]; + } + + return 0; +} +EXPORT_SYMBOL(flex_array_resize); -- 2.1.0