.. include:: ../disclaimer-zh_CN.rst :Original: Documentation/core-api/genalloc.rst :翻译: å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn> :æ ¡è¯‘: 时奎亮 <alexs@kernel.org> .. _cn_core-api_genalloc: genalloc/genpoolå系统 ====================== å†…æ ¸ä¸æœ‰è®¸å¤šå†…å˜åˆ†é…å系统,æ¯ä¸€ä¸ªéƒ½æ˜¯é’ˆå¯¹ç‰¹å®šçš„éœ€æ±‚ã€‚ç„¶è€Œï¼Œæœ‰æ—¶å€™ï¼Œå†…æ ¸å¼€å‘者需 è¦ä¸ºç‰¹å®šèŒƒå›´çš„特殊用途的内å˜å®žçŽ°ä¸€ä¸ªæ–°çš„分é…器;通常这个内å˜ä½äºŽæŸä¸ªè®¾å¤‡ä¸Šã€‚该设 备的驱动程åºçš„作者当然å¯ä»¥å†™ä¸€ä¸ªå°çš„分é…器æ¥å®Œæˆå·¥ä½œï¼Œä½†è¿™æ˜¯è®©å†…æ ¸å……æ»¡å‡ å个测试 差劲的分é…器的方法。早在2005年,Jes Sorensen从sym53c8xx_2驱动ä¸æå–了其ä¸çš„一 个分é…器,并将其作为一个通用模å—å‘布,用于创建特设的内å˜åˆ†é…器。这段代ç 在2.6.13 版本ä¸è¢«åˆå¹¶ï¼›æ¤åŽå®ƒè¢«å¤§å¤§åœ°ä¿®æ”¹äº†ã€‚ .. _posted: https://lwn.net/Articles/125842/ 使用这个分é…器的代ç 应该包括<linux/genalloc.h>ã€‚è¿™ä¸ªåŠ¨ä½œä»Žåˆ›å»ºä¸€ä¸ªæ± å¼€å§‹ï¼Œä½¿ç”¨ 一个: 该APIåœ¨ä»¥ä¸‹å†…æ ¸ä»£ç ä¸: lib/genalloc.c 对gen_pool_create()的调用将创建一个内å˜æ± 。分é…的粒度由min_alloc_order设置;它 是一个log-base-2(以2为底的对数)的数å—,就åƒé¡µé¢åˆ†é…器使用的数å—ä¸€æ ·ï¼Œä½†å®ƒæŒ‡çš„æ˜¯ å—节而ä¸æ˜¯é¡µé¢ã€‚å› æ¤ï¼Œå¦‚æžœmin_alloc_orderè¢«ä¼ é€’ä¸º3,那么所有的分é…将是8å—节的å€æ•°ã€‚ å¢žåŠ min_alloc_orderå¯ä»¥å‡å°‘è·Ÿè¸ªæ± ä¸å†…å˜æ‰€éœ€çš„内å˜ã€‚nidå‚数指定哪一个NUMA节点应该被 用于分é…管家结构体;如果调用者ä¸å…³å¿ƒï¼Œå®ƒå¯ä»¥æ˜¯-1。 “管ç†çš„â€æŽ¥å£devm_gen_pool_create()将内å˜æ± 与一个特定的设备è”系起æ¥ã€‚在其他方é¢ï¼Œ 当给定的设备被销æ¯æ—¶ï¼Œå®ƒå°†è‡ªåŠ¨æ¸…ç†å†…å˜æ± 。 一个内å˜æ± æ± è¢«å…³é—的方法是: 该APIåœ¨ä»¥ä¸‹å†…æ ¸ä»£ç ä¸: lib/genalloc.c 值得注æ„的是,如果在给定的内å˜æ± ä¸ä»æœ‰æœªå®Œæˆçš„分é…,这个函数将采å–相当æžç«¯çš„æ¥éª¤ï¼Œè°ƒç”¨ BUG()ï¼Œä½¿æ•´ä¸ªç³»ç»Ÿå´©æºƒã€‚ä½ å·²ç»è¢«è¦å‘Šäº†ã€‚ 一个新创建的内å˜æ± 没有内å˜å¯ä»¥åˆ†é…。在这ç§çŠ¶æ€ä¸‹ï¼Œå®ƒæ˜¯ç›¸å½“æ— ç”¨çš„ï¼Œæ‰€ä»¥é¦–è¦ä»»åŠ¡ä¹‹ä¸€é€šå¸¸ 是å‘内å˜æ± é‡Œæ·»åŠ å†…å˜ã€‚è¿™å¯ä»¥é€šè¿‡ä»¥ä¸‹æ–¹å¼å®Œæˆ: 该APIåœ¨ä»¥ä¸‹å†…æ ¸ä»£ç ä¸: include/linux/genalloc.h lib/genalloc.c 对gen_pool_add()的调用将把从地å€ï¼ˆåœ¨å†…æ ¸çš„è™šæ‹Ÿåœ°å€ç©ºé—´ï¼‰å¼€å§‹çš„内å˜çš„大å°å—节放入 ç»™å®šçš„æ± ä¸ï¼Œå†æ¬¡ä½¿ç”¨nid作为节点ID进行辅助内å˜åˆ†é…。gen_pool_add_virt()å˜ä½“å°†æ˜¾å¼ ç‰©ç†åœ°å€ä¸Žå†…å˜è”系起æ¥ï¼›åªæœ‰åœ¨å†…å˜æ± 被用于DMA分é…时,这æ‰æ˜¯å¿…è¦çš„。 从内å˜æ± ä¸åˆ†é…内å˜ï¼ˆå¹¶å°†å…¶æ”¾å›žï¼‰çš„函数是: 该APIåœ¨ä»¥ä¸‹å†…æ ¸ä»£ç ä¸: include/linux/genalloc.h lib/genalloc.c æ£å¦‚人们所期望的,gen_pool_alloc()å°†ä»Žç»™å®šçš„æ± ä¸åˆ†é…size<å—节。gen_pool_dma_alloc() å˜é‡åˆ†é…内å˜ç”¨äºŽDMAæ“作,返回dma所指å‘的空间ä¸çš„相关物ç†åœ°å€ã€‚è¿™åªæœ‰åœ¨å†…å˜æ˜¯ç”¨ gen_pool_add_virt()æ·»åŠ çš„æƒ…å†µä¸‹æ‰ä¼šèµ·ä½œç”¨ã€‚请注æ„,这个函数å离了genpool通常使用 æ— ç¬¦å·é•¿å€¼æ¥è¡¨ç¤ºå†…æ ¸åœ°å€çš„模å¼ï¼›å®ƒè¿”回一个void * æ¥ä»£æ›¿ã€‚ 这一切看起æ¥éƒ½æ¯”较简å•ï¼›äº‹å®žä¸Šï¼Œä¸€äº›å¼€å‘者显然认为这太简å•äº†ã€‚毕竟,上é¢çš„接å£æ²¡æœ‰æ 供对分é…函数如何选择返回哪å—特定内å˜çš„控制。如果需è¦è¿™æ ·çš„控制,下é¢çš„函数将是有æ„义 çš„: 该APIåœ¨ä»¥ä¸‹å†…æ ¸ä»£ç ä¸: lib/genalloc.c 使用gen_pool_alloc_algo()进行的分é…指定了一ç§ç”¨äºŽé€‰æ‹©è¦åˆ†é…的内å˜çš„ç®—æ³•ï¼›é»˜è®¤ç®—æ³•å¯ ä»¥ç”¨gen_pool_set_algo()æ¥è®¾ç½®ã€‚æ•°æ®å€¼è¢«ä¼ 递给算法;大多数算法会忽略它,但å¶å°”也会需 è¦å®ƒã€‚当然,人们å¯ä»¥å†™ä¸€ä¸ªç‰¹æ®Šç”¨é€”的算法,但是已ç»æœ‰ä¸€å¥—公平的算法å¯ç”¨äº†: - gen_pool_first_fit是一个简å•çš„åˆé…分é…器;如果没有指定其他算法,这是默认算法。 - gen_pool_first_fit_align强迫分é…有一个特定的对é½æ–¹å¼ï¼ˆé€šè¿‡genpool_data_align结 æž„ä¸çš„æ•°æ®ä¼ 递)。 - gen_pool_first_fit_order_align 按照大å°çš„顺åºæŽ’列分é…。例如,一个60å—节的分é…å°† 以64å—节对é½ã€‚ - gen_pool_best_fit,æ£å¦‚人们所期望的,是一个简å•çš„最佳匹é…分é…器。 - gen_pool_fixed_allocåœ¨æ± ä¸çš„一个特定å移é‡ï¼ˆé€šè¿‡æ•°æ®å‚数在genpool_data_fixed结 æž„ä¸ä¼ 递)进行分é…。如果指定的内å˜ä¸å¯ç”¨ï¼Œåˆ™åˆ†é…失败。 还有一些其他的函数,主è¦æ˜¯ä¸ºäº†æŸ¥è¯¢å†…å˜æ± ä¸çš„å¯ç”¨ç©ºé—´æˆ–è¿ä»£å†…å˜å—ç‰ç›®çš„。然而,大多数 用户应该ä¸éœ€è¦ä»¥ä¸Šæ述的功能。如果幸è¿çš„è¯ï¼Œå¯¹è¿™ä¸ªæ¨¡å—的广泛认识将有助于防æ¢åœ¨æœªæ¥ç¼– 写特殊用途的内å˜åˆ†é…器。 该APIåœ¨ä»¥ä¸‹å†…æ ¸ä»£ç ä¸: lib/genalloc.c