Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752580AbbK3DLM (ORCPT ); Sun, 29 Nov 2015 22:11:12 -0500 Received: from mail-bn1bbn0102.outbound.protection.outlook.com ([157.56.111.102]:35569 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751685AbbK3DLI (ORCPT ); Sun, 29 Nov 2015 22:11:08 -0500 X-Greylist: delayed 871 seconds by postgrey-1.27 at vger.kernel.org; Sun, 29 Nov 2015 22:11:08 EST Authentication-Results: spf=permerror (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none;freescale.mail.onmicrosoft.com; dmarc=none action=none header.from=freescale.com; From: Zhao Qiang To: CC: , , , , , , , Zhao Qiang Subject: [PATCH v13 1/6] genalloc:support memory-allocation with bytes-alignment to genalloc Date: Mon, 30 Nov 2015 10:48:52 +0800 Message-ID: <1448851737-33125-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;BY2FFO11FD044;1:iOsHHEF7E9kJu+hTg41eQ7ImCTEZ8rxtQ1XoirFjW6WxSd9UtmcbcdnYH1i2dQ9FJ/DHY/k79AwEtyZsPE7X7M+bf4FBctp26j3mNHm3FyATdNMBOHBEUyy02Dz966G9PDlRp4Jp3r9ZwWAuKKdMcI5j6gBEc3iCpDQM9ykLVux9ty7HJor1Bo/1H0ukcvtYbtiWgLUB49tf63RARTfUG6ARoJayC36KQObnqUI6ReaJVKQhlcjcImTYzzz7fvfQS6IS/kxj48qRVtnC1u7ihNg+Dkh5RP6tM0JSMTbfwWtwfOQrZDyLP/T+9xcWwChgX4ThWigOgCLvTm87P0Q5U7/wL5HQoU8BkA22dhzNPYBEZVddLkUDZddPXcyzzyvASdERCW96zzzqd6zqRxN3z8xqgGmD0O0McuIvb8OGkkvhMRT3IY69ofW0kGFjhHAn X-Forefront-Antispam-Report: CIP:192.88.158.2;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(448002)(199003)(189002)(69596002)(77096005)(48376002)(19580405001)(36756003)(5003940100001)(92566002)(33646002)(47776003)(19580395003)(6806005)(2351001)(229853001)(586003)(97736004)(4001430100002)(11100500001)(81156007)(50986999)(106466001)(86362001)(110136002)(1096002)(50226001)(5008740100001)(85326001)(50466002)(1220700001)(87936001)(107886002)(5001960100002)(104016004)(189998001);DIR:OUT;SFP:1102;SCL:1;SRVR:BLUPR03MB1476;H:az84smr01.freescale.net;FPR:;SPF:PermError;PTR:InfoDomainNonexistent;A:1;MX:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB1476;2:hyE7mI9FvFlF6t3n7V62kvWw0WoXUV31vMOe2L9KIoFvo6Q299vnfLLcp6KFL2VoPpYURJJv7O+Fw3gYK0hK4Zj0VJz46sz8ngxprg7S7RSIkRGNMpLuQNShAVBNsxcExNbpW7qAPOeYI0TPg5uqFg==;3:uzsIUHk13j6IfdMBhCYUg6xAX8ndheIovuRbjPXKV+e0l1OV8Kmc57Tz0jFOBHLWI82PLnUUEoc2WdyVNMloV7ZrUzpxn2593HCwekCd8dXJZImaKzcKqmUfzsJ4EuyRRsb4l/124mj9jJlxmUnLngpgq1R4/+UryIRmRm77B+7SkUPiLVO1jteANIFG+Pc0kD4Q4RhY7FfmIZcz6/UwGBBpuamy11ng2dxUiHIKmdM=;25:lxXcNTLHIQJE9Vtt4kh6D3R2EclgxorJixdDFNHQIXBTvbANLU5A9w7JdvxtBxzgsJ+uEDAR/nrmTAjBM70dbSfNbxYBiJgIgggU14xoSqUbqnIGvmyzWZcjQSHYZOY6xWU1berel7EDvdFu6ym09IsctzbOgoX9h0OcLIDwnavNxSyQGesneACxT37JQB9rrdfAwlrvm69Xvh/3ARlhmE+aIUVg4/+yBTGevh6t1Y7XfsJIaB3fCtCiTLL/yhKB5caQZQf0HrllQTSAFemvNw== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB1476; X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB1476;20:o+2T46joqySBuReZkl8vx36zn3FOaq0ORzHqeSiXTj1Xp9Lvr5uOA8qj3DuN+XNDucov3AKN9offiQfhRlgG0CRJC3mJn/fg/gjKAHdkUfVUNpXHVpKaarrUEuim2nZvMxsAzL9lwx4iOnR01TGVYlk/+z8LDGYqlo29iuwBF1YLUZJiji7B7II/oJ7NtyWp/+vDf+NIx9kXmocsHv3G8Bcn3bhH6jnV1tHUfO2aaTT/lQLYo5AKDyV/fqj4xGYmW3ApM7cvUESSrn7/K7FIo+32GnUazbway27vGhc1AGDsukfX7U54yvDqp7BmbkZCH/tKixh7xVhwFqJTzbCSGCZbDwPza4e4+aAMHZc1mdw=;4:ZWsE4jOf/nI8CBFSoP01/4wOTueOnzssSx5975iqtfSEdsvuGd5PP+KBfg8i/bhN/9YD4hECUCYDaIcGz3d+A0FwYax5jg+llvyzZpSpiY1Exvys1CdNlxLQV4jPcDqyj3SA4dcvuODvk8snmtKl/zWUqNvaHwOiO5ZA87oF0kmtx60hJw3eSiu8jaciNbMHinb3sGnmtBMrXQuqzOIA4HrfkaPHzz96ZN5BN2Scit/RYVn7cfiiiuymXcH40FBeIqWhHkrcBk1/LmR02T1ahcJQQ6Ci8OSo1AokEVbf2KKz1qoY60zhZaV/+Bxm9HZr8IZbNIi4I8X1v6ZaYKdQlYddXywRdsE3pwGCi/br/kWEQLABL2fVVpXP5tM+1+jyCkV8lnNbWAIHRtVeAs2UUR8QB06VIl4mmsvHDemkmR2jD3TmBVr7/chBk/wSHYsJ X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(101931422205132); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(520078)(8121501046)(5005006)(3002001)(10201501046);SRVR:BLUPR03MB1476;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB1476; X-Forefront-PRVS: 0776C39A48 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BLUPR03MB1476;23:NAM0eQo/3AM/YjiPIkwfm+3AlIgkNdiH+PspiNG+g?= =?us-ascii?Q?EyMasbLvEvt0bXxxabNsy49gXK8jSai7NJisrl82dMXcD+cHkGMZBxrY6D1D?= =?us-ascii?Q?k7/3JDPrKBH5GhMP70Ai2SQ9JsbiflwbwPvEnSJB1kuLK/S0NgttGUaGUUbK?= =?us-ascii?Q?bfcOnIMXYBSaKTog5N3sCz8Dbw75gwF6H9VmB09fVvXc/LFXywrIzcA5Yh7+?= =?us-ascii?Q?dAAfKxaHbboDIsKK6YcMY6eSffTZdcNkHjixMjKmHRsvkEtgy2nPBNqwndZ7?= =?us-ascii?Q?zmxvuRzq5F9p/27kTdBkZHKC45BRgWNdlz+8lITJxGbNT/STenaOhyoI3uwf?= =?us-ascii?Q?mrViHurI4pChdW1DbwCjx2dHnhZiCO2PhhxCHhfsBHwqiihk359+5+BuxdYT?= =?us-ascii?Q?MWK9UYBsVQSwCjcDCNBeKh4dHG53li1+Uv/9R787LUM/PoF38T3e0OSKrxcg?= =?us-ascii?Q?y5NlOGx3wUkX8kZypRYK9ykkc1x9rgtP8JOiYe54ShEoDR1sDebhWYcOSBdv?= =?us-ascii?Q?CCQyVfZWDjXEsqdO4OCcfXEJtSwbulfW1VL42neIN9Uh+AC8yovLxRcgkWTg?= =?us-ascii?Q?LEA2afN9UOY/ZV1Ie10WNzfPTtdFF8LdS7bCl8d8ICr14FGo6Nuy73ibr+vs?= =?us-ascii?Q?Ta/EWFhcILSUehj10LhK3hRH+Hn2/JjVOLqTzyBX9+q/uI26FSOGl7tB8fl1?= =?us-ascii?Q?R3kE3DBUWeikLAdzTMsU1A0wjOT/mK0r+wrfPrE0AjTWqr7yCMfDogH9JvaJ?= =?us-ascii?Q?76i66XIwrHq2TblD4SmAV/0kRTU3MCqS73da/Ua0gNhSSazOp4LRQXJD6nOI?= =?us-ascii?Q?vhFWsseHwIlCmae12ISt4fUYeL76hIbUeNXTcKv6yCsmhUNc7QhWGm/yuKDC?= =?us-ascii?Q?tzc0rxRkREVyux5F3SyVrzf8gL6WdaS/bLHxbgusCtSKPCwsJ9S0EUSt0+cK?= =?us-ascii?Q?Jjcx1PDyLfxW4g4oiD7RSqT3f4pymMJO4TOxmqMRZcu9FmQ0b5ASw7zajBYK?= =?us-ascii?Q?U+Z7oKQscpvZK5pEZyrZ3DuuLm8l4+szVn46wwtRL0L4w=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB1476;5:0eZc7YsEL+YqUBUmlVJFBSVSAs0fRBD4vFPvCiwMJCgy6crHL2wqt8ikXTZqqboXy1t7tdCXEi00y+FmDglRdSpqLUg0sBMp92+mMyJcjx2pPUfPTAv08VxnPRn2fNl+Ilw/xbx0K0MkRcNBFwQiXA==;24:lKFigszMNS/NNGO52lGgSPIFjkrm71AJGCMAyLwlmQnwdaEFl5D+2XTlU4enOpn4Da85djsJiYUohdQfxabQ7wpswX7PbAzuQnf53yattCs= X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Nov 2015 02:56:33.7706 (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: BLUPR03MB1476 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8557 Lines: 241 Bytes alignment is required to manage some special RAM, so add gen_pool_first_fit_align to genalloc, meanwhile add gen_pool_alloc_algo to pass algo in case user layer using more than one algo, and pass data to gen_pool_first_fit_align(modify gen_pool_alloc as a wrapper) Signed-off-by: Zhao Qiang --- Changes for v6: - patches set v6 include a new patch because of using - genalloc to manage QE MURAM, patch 0001 is the new - patch, adding bytes alignment for allocation for use. Changes for v7: - cpm muram also need to use genalloc to manage, it has a function to reserve a specific region of muram, add offset to genpool_data for start addr to be allocated. Changes for v8: - remove supporting reserving a specific region from this patch add a new patch to support it. Changes for v9: - Nil Changes for v10: - Nil Changes for v11: - Nil Changes for v12: - Nil Changes for v13: - add gen_pool_alloc_algo instead of gen_pool_alloc_data to pass algo and data. - rebase include/linux/genalloc.h | 27 +++++++++++++++++---- lib/genalloc.c | 61 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 7ff168d..3c676ce 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -30,10 +30,12 @@ #ifndef __GENALLOC_H__ #define __GENALLOC_H__ +#include #include struct device; struct device_node; +struct gen_pool; /** * Allocation callback function type definition @@ -47,7 +49,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. @@ -75,6 +77,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, @@ -98,6 +107,8 @@ 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_algo(struct gen_pool *, size_t, + genpool_algo_t algo, 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); @@ -110,14 +121,22 @@ 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, const char *name); diff --git a/lib/genalloc.c b/lib/genalloc.c index 116a166..b8cf89d 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -270,6 +270,25 @@ EXPORT_SYMBOL(gen_pool_destroy); */ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) { + return gen_pool_alloc_algo(pool, size, pool->algo, pool->data); +} +EXPORT_SYMBOL(gen_pool_alloc); + +/** + * gen_pool_alloc_algo - allocate special memory from the pool + * @pool: pool to allocate from + * @size: number of bytes to allocate from the pool + * @algo: algorithm passed from caller + * @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_algo(struct gen_pool *pool, size_t size, + genpool_algo_t algo, void *data) +{ struct gen_pool_chunk *chunk; unsigned long addr = 0; int order = pool->min_alloc_order; @@ -290,8 +309,8 @@ 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); + start_bit = algo(chunk->bits, end_bit, start_bit, + nbits, data, pool); if (start_bit >= end_bit) continue; remain = bitmap_set_ll(chunk->bits, start_bit, nbits); @@ -310,7 +329,7 @@ retry: rcu_read_unlock(); return addr; } -EXPORT_SYMBOL(gen_pool_alloc); +EXPORT_SYMBOL(gen_pool_alloc_algo); /** * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage @@ -501,15 +520,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: pool to find the fit region memory from */ 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: pool to get order from + */ +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. @@ -518,10 +564,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: pool to find the fit region memory from */ 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; @@ -537,12 +584,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: pool to find the fit region memory from * * 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; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/