From patchwork Wed Aug 5 06:50:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Qiang X-Patchwork-Id: 503907 X-Patchwork-Delegate: scottwood@freescale.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6E0FD140342 for ; Wed, 5 Aug 2015 17:11:31 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3C1611A1819 for ; Wed, 5 Aug 2015 17:11:31 +1000 (AEST) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from na01-by2-obe.outbound.protection.outlook.com (mail-by2on0106.outbound.protection.outlook.com [207.46.100.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 5B8A71A1C07 for ; Wed, 5 Aug 2015 17:09:46 +1000 (AEST) Received: from BN3PR0301CA0032.namprd03.prod.outlook.com (10.160.180.170) by BY1PR03MB1483.namprd03.prod.outlook.com (10.162.210.141) with Microsoft SMTP Server (TLS) id 15.1.225.19; Wed, 5 Aug 2015 06:55:16 +0000 Received: from BN1BFFO11FD045.protection.gbl (2a01:111:f400:7c10::1:162) by BN3PR0301CA0032.outlook.office365.com (2a01:111:e400:4000::42) with Microsoft SMTP Server (TLS) id 15.1.225.19 via Frontend Transport; Wed, 5 Aug 2015 06:55:16 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BN1BFFO11FD045.mail.protection.outlook.com (10.58.145.0) with Microsoft SMTP Server (TLS) id 15.1.243.9 via Frontend Transport; Wed, 5 Aug 2015 06:55:16 +0000 Received: from titan.ap.freescale.net ([10.192.208.233]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id t756tB5D019528; Tue, 4 Aug 2015 23:55:11 -0700 From: Zhao Qiang To: Subject: [RFC v4] genalloc:support memory-allocation with bytes-alignment to genalloc Date: Wed, 5 Aug 2015 14:50:04 +0800 Message-ID: <1438757404-17777-1-git-send-email-qiang.zhao@freescale.com> X-Mailer: git-send-email 2.1.0.27.g96db324 X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD045; 1:mKBrEF47KNpi9QCjp/jU9Xt9O0sgTb7ReAnBbX9I88NCRnydXtCv2t3z7p6xGx0TORYZ31rE+SZAH5LLD1+szkgBqBC4yg5urhFE6L5KkKNqS/wrDfmLIHM3EK5WOYEYt8W0uqU380ouu7/lIC7uFnJu6gtZ2cGdaerPRug0Wy7PauA7rCYmlJsrV43J0BFMQykozBectJaXHjvA3gEjkf9zklm/3vTS6DgZMve0FaP5nZzueTGgJ2WUKIN1h/OCx9eE1oJEe5SmTATZpG5RZI9TvwvA9OEA2ZvS99xSMeBvtF3AxzZ+KspvyQ7c6Jrbcp3az4hKOJbKDLsqVQ4diA== X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(2980300002)(339900001)(189002)(199003)(69596002)(4001540100001)(5003940100001)(50986999)(85426001)(50226001)(47776003)(64706001)(105606002)(33646002)(104016003)(46102003)(15975445007)(48376002)(81156007)(5001830100001)(86362001)(110136002)(62966003)(229853001)(5001860100001)(5001960100002)(97736004)(87936001)(2351001)(107886002)(92566002)(68736005)(19580405001)(77096005)(50466002)(6806004)(189998001)(36756003)(77156002)(19580395003)(106466001)(4001430100001); DIR:OUT; SFP:1102; SCL:1; SRVR:BY1PR03MB1483; H:az84smr01.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BY1PR03MB1483; 2:K/2zCKmyJd35wyVbpP+8FdVuHTpIynHi6PhfbVJkZBOOHDMBwvDaDKG+VcrsTIsDqEBtn4gIxzpJwgtliFj4e91Ed/W7PcpRCYlhov4iw8Ti+IDZ9OPOufHs1E90UzxvhmZv/kduRGdZLJKA2Y8VauMrnWZSlsF955zA2LkRXpM=; 3:4sF2gcZta1DrBrT5Gx02z/oCYx6fRBmz/eu9dIxTgaFQWsgJAZbioH0Aq1oxvK6eILuStQesDhoKJcXP5dj+NDJuDgSb8yUSwFGeC73QWCPB+Klvw4I14CtzElesEOq7WogbgbLSDX48ZIdqkMQw3H3LV6YoPwcBRuFwUDbpAuQ4KCvq6K6UEg6blTqc9WhPSTvuETrUqawZ8nJkrqqEJkCn0yfCqz5xo5g6eNTIeyI=; 25:/0xnEcOWRUfVovQ48hJIqSvoGiRDtfu6pxYmesXhgIwst5lO0en6BLUa8lmq34Bz4nqX7Vv10DEv70zcOBgLh81qlOSkFjEorPBj6kV7grp7cc+xsma5M7e7uXLuJ6zyk5QIirPzjVrCdoGG2jmv9uGY+tlahb4aBD2ynMG0hHzWGG56J8H0hAiqUyzGm1TzcAE0SXzUJ/C4VaZswnNGg1AFvni/tsafOPIuDWAeqkvVHNwomHOqXgOTuiwfPXumkTdwjFkq2sNnGIq74gxi1A== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR03MB1483; X-Microsoft-Exchange-Diagnostics: 1; BY1PR03MB1483; 20:KiBPPicPAtNeqTVT+RFnAZT8xN8lwYMOFcwlpvguK6WmMxhHlAfvXV3sYAjcIWubZETbJfWmNOr6AdqdZAV6En1j5T6H8HjC5fvt36MT4Ykhg4L/zDZ4oHm3BCd1nVAr2TA+sj/x5FyU939qnqmeMdWG9lVrI9DBohWqvEczNUTsFYnB6QNFMXVHYXQmiTdIfP/qJ5EcOMut55vrv8frJUeptXhuVrJUB0lELkZPDZNE5eqlP2/NjgY8Z/sfj1ryLe/6lvHNH1y1KhpoCLg+Juy8ax2aIPD8TeSEoLCQKrVu6538NhUvfB6nGOaTPoPQCabEBbbbK0akh92PmdBMYrD+nAGwiRTibFZRFjIsv/8=; 4:4Bp2sCd3aL/6RhuBF6ldTu8ur11GtLL3NNh+bQyq10jRamWsRiRsmci3dqmaFl1X5ByXtgES/9egzKaqPKMWrY9FTZgHB+UsZypUSug/C9WMwAej6srDpa/FSIMWsZ+SqrvTWsoR9EsTZjGbDRUXv6YXFr4bRVHTVoyYhCyGbkusZUBuL4ObJC3t04cwi8uTCU0wu9ukevRbMeaY+fsiANnlrFGi+LAflZNkcG1lWDPYVtIgt140CJbauf4dXPGnyGa1m8vPQVsmiXMoy38BM5kyltngtYmLiQvDq3HEz+o= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:BY1PR03MB1483; BCL:0; PCL:0; RULEID:; SRVR:BY1PR03MB1483; X-Forefront-PRVS: 06592CCE58 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY1PR03MB1483; 23:9egdXGt2SOBM34xizqHlFQMZzHj/LwLajvbNdAVOV?= =?us-ascii?Q?VGY/lFwyGfgZHF8IPvk2nUXdjIgBJ6BXnWpj8OyDdUBLgjozCEUv4MmcVQqM?= =?us-ascii?Q?H5rtxBUVADkjz2kdWIG4EUXqoR5mpFEmWOWOpIWOlYrzUyqWF1kd7inaIkrs?= =?us-ascii?Q?ElyxIQU1Le/2svYiqYaDgjUOk5m7cbe6fnlotFzsjo04xm1AaeGeb7Son1+Q?= =?us-ascii?Q?Ce2yR+KMCfPHiKVOAwzJx1IKNXxWmoToBe5uppJ1J4jRQ6rKhjnJqyHfzIii?= =?us-ascii?Q?IvadcHCFTrcozTWQWq9+EhhCoMLNqnTpDRuhzHekXamdEZHPlFBVGjLvH/qg?= =?us-ascii?Q?0wYSUkeSERT2dUAtNQu0xPle9PRwATTTIkTazH7U2krlLwUtX7EfqJ/s8b2J?= =?us-ascii?Q?M78qF/k7TtfqouuXvuIVyej1f9a85YgX3CFdk/oitNrcbCaRzB9glBXd3kV/?= =?us-ascii?Q?ToRShlQHy5FzhHxZmnIxZlDSRnnAffppGXFzPGvppre10rTpujP2vZM6yx56?= =?us-ascii?Q?latNcn7Oxlsl1YP7/j9guKaatgq9zh5TWBSHP3sXDUgcf8MymWNsb7599xEr?= =?us-ascii?Q?PGzVhGPgh8UIRwYIxGBirI7ZqLyDo2IrMRMASHrOxh3gf8HTQ2CzEmbNHMoh?= =?us-ascii?Q?uJee6sEHV3nz/uDAMBctyf+h+Imug1nKMfQ73JDMvSltk/BUzy14oFXzMNIt?= =?us-ascii?Q?pzcuR3UoKgGTzW0FS/x4ba2/BRy6ME2VHzGDLsYosVEYs64lCdMCdN8dESL4?= =?us-ascii?Q?Sk35Aol8dV2qFR+9pRYUU6flAXBTgNRUyny/IlyuW6tC02xtgsm97ceJS3+T?= =?us-ascii?Q?golqHnvEkEpa+dh+oIXzsf5auJBnxjIamgzkyXVwVBkOSZb7eF182ZPIUf0I?= =?us-ascii?Q?cRG/E0Yet6t0nQ6WXmeChXGYraWj0c6hURIWil9ZRGc+kH7exZ1OVHxZipDI?= =?us-ascii?Q?e2vZazlkhTDq3il1m1xUhkrda1R1mJ8BdgQ5vjgY0N4s1ds8SvLLea+z04xt?= =?us-ascii?Q?tckRDqcUTsXKTgctI1yC4bB8Emjk7VouWQlcqlMc/G3LuSvVTXrJaoUOT9Gk?= =?us-ascii?Q?B01UZY6VAvTpZErKbDpLjHIZSXgjiFWruxTpfZpa/hn3FSEXWTasI0d+czxJ?= =?us-ascii?Q?bQFOyXy5nBc2GeVtHFy0hjDybP2x/tA?= X-Microsoft-Exchange-Diagnostics: 1; BY1PR03MB1483; 5:S312x5aq1oXPQv8Dfxo0c001wcevT9uYLduV5CP3llY7v8Ywg9g3F1U5+lYNC067UaouI3tau9WnirYyMkcylSEOZ4JbvejUSlpI9p8JC3Y/WAx3hI2PnTHF4ietaZbapoK0aCFkLtDsIFnTur8Ymw==; 24:o7IT37FvQ5OGMHMWn3rp2MTVBU/qxFcZRSrAWA8I91QG/ncmhwzPNwf/k7JrDXdFaGQ025+7H7qh/szEnyoTmNqbnv+ut7lvnFbKDKI3LUE=; 20:Xz3Qq8Mpgxfe8LhghmIWSSAIfPtSqtQBYwpWGDPg78nZto8AbWTFEHvFGYBBMXCytV/Y2SagTR/WFl3P3RbabQ== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Aug 2015 06:55:16.0371 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR03MB1483 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zhao Qiang , catalin.marinas@arm.com, linux-kernel@vger.kernel.org, scottwood@freescale.com, olof@lixom.net, akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org, X.xie@freescale.com Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Bytes alignment is required to manage some special RAM, so add gen_pool_first_fit_align to genalloc, meanwhile add gen_pool_alloc_data to pass data to gen_pool_first_fit_align(modify gen_pool_alloc as a wrapper) Signed-off-by: Zhao Qiang --- *v2: changes: title has been modified, original patch link: http://patchwork.ozlabs.org/patch/493297/ original patch add a func gen_pool_alloc_align, then pass alignment to it as an parameter. after discussing with lauraa and scott, they recommend to pass alignment as part of data based on commit message for ca279cf1065fb689abea1dc7d8c11787729bb185 which adds "data": "As I can't predict all the possible requirements/needs for all allocation uses cases, I add a "free" field 'void *data' to pass any needed information to the allocation function. For example 'data' could be used to handle a structure where you store the alignment, the expected memory bank, the requester device, or any information that could influence the allocation algorithm." *v3: changes: title has been modified, original patch link: http://patchwork.ozlabs.org/patch/500317/ according to the comments, add gen_pool_alloc_data, modify gen_pool_alloc as a wrapper, define struct data_align for gen_pool_first_fit_align algorithm. add parameter pointer pool to algorithm. *v4: changes: v3 link: http://patchwork.ozlabs.org/patch/500317/ There are comments for v3, according to the comments, modify the patch for v4. such as modifying annotations, removing unnecessary chek, removing unnecessary cast and so on. include/linux/genalloc.h | 23 +++++++++++++++---- lib/genalloc.c | 58 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 1ccaab4..55da07e 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -34,6 +34,7 @@ struct device; struct device_node; +struct gen_pool; /** * Allocation callback function type definition @@ -47,7 +48,7 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data); + void *data, struct gen_pool *pool); /* * General purpose special memory pool descriptor. @@ -73,6 +74,13 @@ struct gen_pool_chunk { unsigned long bits[0]; /* bitmap for allocating memory chunk */ }; +/* + * gen_pool data descriptor for gen_pool_first_fit_align. + */ +struct genpool_data_align { + int align; /* alignment by bytes for starting address */ +}; + extern struct gen_pool *gen_pool_create(int, int); extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, @@ -96,6 +104,7 @@ static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, } extern void gen_pool_destroy(struct gen_pool *); extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); +extern unsigned long gen_pool_alloc_data(struct gen_pool *, size_t, void *data); extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); @@ -108,14 +117,20 @@ extern void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, void *data); extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data); + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool); + +extern unsigned long gen_pool_first_fit_align(unsigned long *map, + unsigned long size, unsigned long start, unsigned int nr, + void *data, struct gen_pool *pool); extern unsigned long gen_pool_first_fit_order_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data); + void *data, struct gen_pool *pool); extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data); + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool); extern struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, int nid); diff --git a/lib/genalloc.c b/lib/genalloc.c index d214866..fe11a00 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -269,6 +269,24 @@ EXPORT_SYMBOL(gen_pool_destroy); */ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) { + return gen_pool_alloc_data(pool, size, pool->data); +} +EXPORT_SYMBOL(gen_pool_alloc); + +/** + * gen_pool_alloc_data - allocate special memory from the pool + * @pool: pool to allocate from + * @size: number of bytes to allocate from the pool + * @data: data passed to algorithm + * + * Allocate the requested number of bytes from the specified pool. + * Uses the pool allocation function (with first-fit algorithm by default). + * Can not be used in NMI handler on architectures without + * NMI-safe cmpxchg implementation. + */ +unsigned long gen_pool_alloc_data(struct gen_pool *pool, size_t size, + void *data) +{ struct gen_pool_chunk *chunk; unsigned long addr = 0; int order = pool->min_alloc_order; @@ -290,7 +308,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) end_bit = chunk_size(chunk) >> order; retry: start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits, - pool->data); + data, pool); if (start_bit >= end_bit) continue; remain = bitmap_set_ll(chunk->bits, start_bit, nbits); @@ -309,7 +327,7 @@ retry: rcu_read_unlock(); return addr; } -EXPORT_SYMBOL(gen_pool_alloc); +EXPORT_SYMBOL(gen_pool_alloc_data); /** * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage @@ -500,15 +518,42 @@ EXPORT_SYMBOL(gen_pool_set_algo); * @start: The bitnumber to start searching at * @nr: The number of zeroed bits we're looking for * @data: additional data - unused + * @pool: unused, but the algorithm functions have same format. */ unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data) + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool) { return bitmap_find_next_zero_area(map, size, start, nr, 0); } EXPORT_SYMBOL(gen_pool_first_fit); /** + * gen_pool_first_fit_align - find the first available region + * of memory matching the size requirement (alignment constraint) + * @map: The address to base the search on + * @size: The bitmap size in bits + * @start: The bitnumber to start searching at + * @nr: The number of zeroed bits we're looking for + * @data: data for alignment + * @pool: get order from pool + */ +unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool) +{ + struct genpool_data_align *alignment; + unsigned long align_mask; + int order; + + alignment = data; + order = pool->min_alloc_order; + align_mask = ((alignment->align + (1UL << order) - 1) >> order) - 1; + return bitmap_find_next_zero_area(map, size, start, nr, align_mask); +} +EXPORT_SYMBOL(gen_pool_first_fit_align); + +/** * gen_pool_first_fit_order_align - find the first available region * of memory matching the size requirement. The region will be aligned * to the order of the size specified. @@ -517,10 +562,11 @@ EXPORT_SYMBOL(gen_pool_first_fit); * @start: The bitnumber to start searching at * @nr: The number of zeroed bits we're looking for * @data: additional data - unused + * @pool: unused, but the algorithm functions have same format. */ unsigned long gen_pool_first_fit_order_align(unsigned long *map, unsigned long size, unsigned long start, - unsigned int nr, void *data) + unsigned int nr, void *data, struct gen_pool *pool) { unsigned long align_mask = roundup_pow_of_two(nr) - 1; @@ -536,12 +582,14 @@ EXPORT_SYMBOL(gen_pool_first_fit_order_align); * @start: The bitnumber to start searching at * @nr: The number of zeroed bits we're looking for * @data: additional data - unused + * @pool: unused, but the algorithm functions have same format. * * Iterate over the bitmap to find the smallest free region * which we can allocate the memory. */ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data) + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool) { unsigned long start_bit = size; unsigned long len = size + 1;