Re: [PATCH/RESEND] mm: add ztree - new allocator for use via zpool API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ananda,

I love your patch! Perhaps something to improve:

[auto build test WARNING on hnaz-mm/master]

url:    https://github.com/0day-ci/linux/commits/Ananda/mm-add-ztree-new-allocator-for-use-via-zpool-API/20220228-190619
base:   https://github.com/hnaz/linux-mm master
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20220228/202202282010.qo0U7ATX-lkp@xxxxxxxxx/config)
compiler: sh4-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/a30d4197bd92974faeafba46d6e74d3d8943c88c
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Ananda/mm-add-ztree-new-allocator-for-use-via-zpool-API/20220228-190619
        git checkout a30d4197bd92974faeafba46d6e74d3d8943c88c
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=sh SHELL=/bin/bash M=mm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>

All warnings (new ones prefixed by >>):

>> mm/ztree.c:236:6: warning: no previous prototype for 'free_block_tree' [-Wmissing-prototypes]
     236 | void free_block_tree(struct ztree_pool *pool, int block_type)
         |      ^~~~~~~~~~~~~~~
>> mm/ztree.c:282:20: warning: no previous prototype for 'ztree_create_pool' [-Wmissing-prototypes]
     282 | struct ztree_pool *ztree_create_pool(gfp_t gfp, const struct ztree_ops *ops)
         |                    ^~~~~~~~~~~~~~~~~
>> mm/ztree.c:327:6: warning: no previous prototype for 'ztree_destroy_pool' [-Wmissing-prototypes]
     327 | void ztree_destroy_pool(struct ztree_pool *pool)
         |      ^~~~~~~~~~~~~~~~~~
>> mm/ztree.c:350:5: warning: no previous prototype for 'ztree_alloc' [-Wmissing-prototypes]
     350 | int ztree_alloc(struct ztree_pool *pool, size_t size, gfp_t gfp,
         |     ^~~~~~~~~~~
>> mm/ztree.c:414:6: warning: no previous prototype for 'ztree_free' [-Wmissing-prototypes]
     414 | void ztree_free(struct ztree_pool *pool, unsigned long handle)
         |      ^~~~~~~~~~
>> mm/ztree.c:474:5: warning: no previous prototype for 'ztree_reclaim_block' [-Wmissing-prototypes]
     474 | int ztree_reclaim_block(struct ztree_pool *pool)
         |     ^~~~~~~~~~~~~~~~~~~
>> mm/ztree.c:554:7: warning: no previous prototype for 'ztree_map' [-Wmissing-prototypes]
     554 | void *ztree_map(struct ztree_pool *pool, unsigned long handle)
         |       ^~~~~~~~~
>> mm/ztree.c:591:6: warning: no previous prototype for 'ztree_unmap' [-Wmissing-prototypes]
     591 | void ztree_unmap(struct ztree_pool *pool, unsigned long handle)
         |      ^~~~~~~~~~~
>> mm/ztree.c:628:5: warning: no previous prototype for 'ztree_get_pool_size' [-Wmissing-prototypes]
     628 | u64 ztree_get_pool_size(struct ztree_pool *pool)
         |     ^~~~~~~~~~~~~~~~~~~

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for SND_SOC_LPASS_RX_MACRO
   Depends on SOUND && !UML && SND && SND_SOC && COMMON_CLK
   Selected by
   - SND_SOC_SC7280 && SOUND && !UML && SND && SND_SOC && SND_SOC_QCOM && I2C && SOUNDWIRE
   WARNING: unmet direct dependencies detected for SND_SOC_LPASS_TX_MACRO
   Depends on SOUND && !UML && SND && SND_SOC && COMMON_CLK
   Selected by
   - SND_SOC_SC7280 && SOUND && !UML && SND && SND_SOC && SND_SOC_QCOM && I2C && SOUNDWIRE


vim +/free_block_tree +236 mm/ztree.c

   231	
   232	
   233	/*
   234	 * free block tree with blocks of particular type
   235	 */
 > 236	void free_block_tree(struct ztree_pool *pool, int block_type)
   237	{
   238		struct ztree_block *block, *tmp;
   239		struct block_tree *tree;
   240	
   241		tree = &(pool->block_trees)[block_type];
   242		spin_lock(&tree->lock);
   243		rbtree_postorder_for_each_entry_safe(block, tmp, &tree->root, block_node) {
   244			free_pages((unsigned long)block->compressed_data,
   245						tree_desc[block_type].order);
   246			kmem_cache_free(pool->block_cache, block);
   247		}
   248		spin_unlock(&tree->lock);
   249	}
   250	
   251	/*
   252	 * Encodes the handle of a particular slot in the pool using metadata
   253	 */
   254	static inline unsigned long metadata_to_handle(unsigned long block_type,
   255						unsigned long block_index, unsigned long slot)
   256	{
   257		return (block_type << BLOCK_TYPE_SHIFT) + (block_index << SLOT_BITS) + slot;
   258	}
   259	
   260	
   261	/* Returns block type, block index and slot in the pool corresponding to handle */
   262	static inline void handle_to_metadata(unsigned long handle, unsigned long *block_type,
   263							unsigned long *block_index, unsigned long *slot)
   264	{
   265		*block_type = handle >> BLOCK_TYPE_SHIFT;
   266		*block_index = (handle & BLOCK_INDEX_MASK) >> SLOT_BITS;
   267		*slot = handle & SLOT_MASK;
   268	}
   269	
   270	
   271	/*****************
   272	 * API Functions
   273	 *****************/
   274	/**
   275	 * ztree_create_pool() - create a new ztree pool array
   276	 * @gfp:	gfp flags when allocating the ztree pool structure
   277	 * @ops:	user-defined operations for the ztree pool
   278	 *
   279	 * Return: pointer to the new ztree pool or NULL if the metadata allocation
   280	 * failed.
   281	 */
 > 282	struct ztree_pool *ztree_create_pool(gfp_t gfp, const struct ztree_ops *ops)
   283	{
   284		struct ztree_pool *pool;
   285		struct block_tree *tree;
   286		int i, block_types_nr;
   287	
   288		pool = kmalloc(sizeof(struct ztree_pool), gfp);
   289		if (!pool)
   290			return NULL;
   291	
   292		block_types_nr = ARRAY_SIZE(tree_desc);
   293	
   294		pool->block_cache = kmem_cache_create("ztree_blocks",
   295						sizeof(struct ztree_block), 0, 0, NULL);
   296		if (!pool->block_cache) {
   297			kfree(pool);
   298			return NULL;
   299		}
   300	
   301		pool->block_trees = kmalloc(block_types_nr * sizeof(struct block_tree), gfp);
   302		if (!pool->block_trees) {
   303			kmem_cache_destroy(pool->block_cache);
   304			kfree(pool);
   305			return NULL;
   306		}
   307	
   308		/* init each basic block tree */
   309		for (i = 0; i < block_types_nr; i++) {
   310			tree = &(pool->block_trees)[i];
   311			spin_lock_init(&tree->lock);
   312			tree->root = RB_ROOT;
   313			tree->last_block = NULL;
   314			tree->current_block = NULL;
   315			tree->counter = 0;
   316			tree->block_count = 0;
   317		}
   318		pool->ops = ops;
   319		return pool;
   320	}
   321	
   322	/**
   323	 * ztree_destroy_pool() - destroys an existing ztree pool
   324	 * @pool:	the ztree pool to be destroyed
   325	 *
   326	 */
 > 327	void ztree_destroy_pool(struct ztree_pool *pool)
   328	{
   329		int i;
   330	
   331		for (i = 0; i < ARRAY_SIZE(tree_desc); i++)
   332			free_block_tree(pool, i);
   333		kmem_cache_destroy(pool->block_cache);
   334		kfree(pool->block_trees);
   335		kfree(pool);
   336	}
   337	
   338	
   339	/**
   340	 * ztree_alloc() - allocates a slot of appropriate size
   341	 * @pool:	ztree pool from which to allocate
   342	 * @size:	size in bytes of the desired allocation
   343	 * @gfp:	gfp flags used if the pool needs to grow
   344	 * @handle:	handle of the new allocation
   345	 *
   346	 * Return: 0 if success and handle is set, otherwise -EINVAL if the size or
   347	 * gfp arguments are invalid or -ENOMEM if the pool was unable to allocate
   348	 * a new slot.
   349	 */
 > 350	int ztree_alloc(struct ztree_pool *pool, size_t size, gfp_t gfp,
   351				unsigned long *handle)
   352	{
   353		unsigned long block_type, slot;
   354		struct ztree_block *block;
   355		struct block_tree *tree;
   356	
   357		if (!size)
   358			return -EINVAL;
   359	
   360		if (size > PAGE_SIZE)
   361			return -ENOSPC;
   362	
   363		/* find basic block type with suitable slot size */
   364		for (block_type = 0; block_type < ARRAY_SIZE(tree_desc); block_type++) {
   365			if (size <= tree_desc[block_type].slot_size)
   366				break;
   367		}
   368		tree = &(pool->block_trees[block_type]);
   369		spin_lock(&tree->lock);
   370		/* check if there are free slots in the current and the last added blocks */
   371		if (tree->current_block && tree->current_block->free_slots > 0) {
   372			block = tree->current_block;
   373			goto found;
   374		}
   375		if (tree->last_block && tree->last_block->free_slots > 0) {
   376			block = tree->last_block;
   377			goto found;
   378		}
   379		spin_unlock(&tree->lock);
   380	
   381		/* not found block with free slots try to allocate new empty block */
   382		block = alloc_block(pool, block_type, gfp);
   383		spin_lock(&tree->lock);
   384		if (block) {
   385			tree->current_block = block;
   386			goto found;
   387		}
   388		spin_unlock(&tree->lock);
   389		return -ENOMEM;
   390	
   391	found:
   392		spin_lock(&block->lock);
   393		block->free_slots--;
   394		spin_unlock(&tree->lock);
   395		/* find the first free slot in block */
   396		for (slot = 0; slot < tree_desc[block_type].slots_per_block; slot++) {
   397			if (block->slot_info[slot] == SLOT_FREE)
   398				break;
   399		}
   400		block->slot_info[slot] = SLOT_OCCUPIED;
   401		block->coeff = block->free_slots *
   402				(tree_desc[block_type].slots_per_block - block->free_slots);
   403		spin_unlock(&block->lock);
   404		*handle = metadata_to_handle(block_type, block->block_index, slot);
   405		return 0;
   406	}
   407	
   408	/**
   409	 * ztree_free() - frees the allocation associated with the given handle
   410	 * @pool:	pool in which the allocation resided
   411	 * @handle:	handle associated with the allocation returned by ztree_alloc()
   412	 *
   413	 */
 > 414	void ztree_free(struct ztree_pool *pool, unsigned long handle)
   415	{
   416		unsigned long slot, block_type, block_index;
   417		struct rb_node *tmp;
   418		struct ztree_block *block;
   419		struct block_tree *tree;
   420	
   421		handle_to_metadata(handle, &block_type, &block_index, &slot);
   422		tree = &(pool->block_trees[block_type]);
   423	
   424		/* find block corresponding to handle */
   425		spin_lock(&tree->lock);
   426		tmp = rb_find(&block_index, &tree->root, index_comp);
   427		if (!tmp) {
   428			spin_unlock(&tree->lock);
   429			pr_err("ztree block not found\n");
   430			return;
   431		}
   432		block = rb_entry(tmp, struct ztree_block, block_node);
   433		if (block->under_reclaim) {
   434			spin_unlock(&tree->lock);
   435			return;
   436		}
   437		block->free_slots++;
   438		/* if all slots in block are empty delete whole block */
   439		if (block->free_slots == tree_desc[block_type].slots_per_block) {
   440			rb_erase(&block->block_node, &tree->root);
   441			tree->block_count--;
   442	
   443			/* if the last block to be deleted */
   444			if (block == tree->last_block) {
   445				tree->current_block = NULL;
   446				tree->last_block = NULL;
   447			/* otherwise set current block to last block */
   448			} else {
   449				tree->current_block = tree->last_block;
   450			}
   451			spin_unlock(&tree->lock);
   452			free_pages((unsigned long)block->compressed_data, tree_desc[block_type].order);
   453			kmem_cache_free(pool->block_cache, block);
   454			return;
   455		}
   456		/* switch current block */
   457		if (!tree->current_block || block->coeff >= tree->current_block->coeff)
   458			tree->current_block = block;
   459		spin_lock(&block->lock);
   460		spin_unlock(&tree->lock);
   461		block->slot_info[slot] = SLOT_FREE;
   462		block->coeff = block->free_slots *
   463					(tree_desc[block_type].slots_per_block - block->free_slots);
   464		spin_unlock(&block->lock);
   465	}
   466	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux