mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jeff Garzik <jeff@garzik.org>
To: anil.s.keshavamurthy@intel.com
Cc: linux-kernel@vger.kernel.org, akpm@osdl.org, ak@suse.de,
	gregkh@suse.de, muli@il.ibm.com, asit.k.mallick@intel.com,
	suresh.b.siddha@intel.com, arjan@linux.intel.com,
	ashok.raj@intel.com, shaohua.li@intel.com, davem@davemloft.net
Subject: Re: [Intel-IOMMU 02/10] Library routines for handling pre-allocated pool of objects
Date: Mon, 4 Jun 2007 18:57:14 -0400	[thread overview]
Message-ID: <20070604225714.GM20299@havoc.gtf.org> (raw)
In-Reply-To: <20070604210644.156875000@askeshav-devel.jf.intel.com>

On Mon, Jun 04, 2007 at 02:02:44PM -0700, anil.s.keshavamurthy@intel.com wrote:
> 	This patch provides a common interface for pre allocating and 
> managing pool of objects.
> 
> Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
> ---
>  include/linux/respool.h |   43 +++++++++++
>  lib/Makefile            |    1 
>  lib/respool.c           |  176 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 220 insertions(+)
> 
> Index: linux-2.6.22-rc3/include/linux/respool.h
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ linux-2.6.22-rc3/include/linux/respool.h	2007-06-04 12:36:17.000000000 -0700
> @@ -0,0 +1,43 @@
> +/*
> + * respool.c - library routines for handling generic pre-allocated pool of objects
> + *
> + * Copyright (c) 2006, Intel Corporation.
> + *
> + * This file is released under the GPLv2.
> + *
> + * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
> + *
> + */
> +
> +#ifndef _RESPOOL_H_
> +#define _RESPOOL_H_
> +
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/workqueue.h>
> +
> +typedef void *(*rpool_alloc_t)(unsigned int, gfp_t);
> +typedef void (*rpool_free_t)(void *, unsigned int);
> +
> +struct resource_pool {
> +	struct work_struct work;
> +	spinlock_t	pool_lock;	/* pool lock to walk the pool_head */
> +	struct list_head pool_head;	/* pool objects list head	*/
> +	unsigned int	min_count;	/* min count to maintain	*/
> +	unsigned int	grow_count;	/* grow by count when time to grow */
> +	unsigned int	curr_count;	/* count of current free objects */
> +	unsigned int	alloc_size;	/* objects size			*/
> +	rpool_alloc_t 	alloc_mem;	/* pool mem alloc function pointer */
> +	rpool_free_t 	free_mem;	/* pool mem free function pointer */
> +};
> +
> +void *get_resource_pool_obj(struct resource_pool *ppool);
> +void put_resource_pool_obj(void * vaddr, struct resource_pool *ppool);
> +void destroy_resource_pool(struct resource_pool *ppool);
> +int init_resource_pool(struct resource_pool *res,
> +	unsigned int min_count, unsigned int alloc_size,
> +	unsigned int grow_count, rpool_alloc_t alloc_fn,
> +	rpool_free_t free_fn);
> +
> +#endif
> Index: linux-2.6.22-rc3/lib/Makefile
> ===================================================================
> --- linux-2.6.22-rc3.orig/lib/Makefile	2007-06-04 12:28:10.000000000 -0700
> +++ linux-2.6.22-rc3/lib/Makefile	2007-06-04 12:36:17.000000000 -0700
> @@ -58,6 +58,7 @@
>  obj-$(CONFIG_AUDIT_GENERIC) += audit.o
>  
>  obj-$(CONFIG_SWIOTLB) += swiotlb.o
> +obj-$(CONFIG_DMAR) += respool.o
>  obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
>  
>  lib-$(CONFIG_GENERIC_BUG) += bug.o
> Index: linux-2.6.22-rc3/lib/respool.c
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ linux-2.6.22-rc3/lib/respool.c	2007-06-04 12:36:17.000000000 -0700
> @@ -0,0 +1,176 @@
> +/*
> + * respool.c - library routines for handling generic pre-allocated pool of objects
> + *
> + * Copyright (c) 2006, Intel Corporation.
> + *
> + * This file is released under the GPLv2.
> + *
> + * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
> + */
> +
> +#include <linux/respool.h>
> +
> +/**
> + * get_resource_pool_obj - gets an object from the pool
> + * @ppool - resource pool in question
> + * This function gets an object from the pool and
> + * if the pool count drops below min_count, this
> + * function schedules work to grow the pool. If
> + * no elements are fount in the pool then this function
> + * tries to get memory from kernel.
> + */
> +void * get_resource_pool_obj(struct resource_pool *ppool)
> +{
> +	unsigned long	flags;
> +	struct list_head *plist;
> +	bool queue_work = 0;
> +
> +	spin_lock_irqsave(&ppool->pool_lock, flags);
> +	if (!list_empty(&ppool->pool_head)) {
> +		plist = ppool->pool_head.next;
> +		list_del(plist);
> +		ppool->curr_count--;
> +	} else {
> +		/*Making sure that curr_count is 0 when list is empty */
> +		plist = NULL;
> +		BUG_ON(ppool->curr_count != 0);
> +	}
> +
> +	/* Check if pool needs to grow */
> +	if (ppool->curr_count <= ppool->min_count)
> +		queue_work = 1;
> +	spin_unlock_irqrestore(&ppool->pool_lock, flags);
> +
> +	if (queue_work)
> +		schedule_work(&ppool->work); /* queue work to grow the pool */
> +
> +
> +	if (plist) {
> +		memset(plist, 0, ppool->alloc_size); /* Zero out memory */
> +		return plist;
> +	}
> +
> +	/* Out of luck, try to get memory from kernel */
> +	plist = (struct list_head *)ppool->alloc_mem(ppool->alloc_size,
> +			GFP_ATOMIC);

Since you are outside the lock, you should pass in gfp_flags, to enhance
the chance of being able to use GFP_KERNEL in certain contexts.


> +	return plist;
> +}
> +
> +/**
> + * put_resource_pool_obj - puts an object back to the pool
> + * @vaddr - object's address
> + * @ppool - resource pool in question.
> + * This function puts an object back to the pool.
> + */
> +void put_resource_pool_obj(void * vaddr, struct resource_pool *ppool)
> +{
> +	unsigned long	flags;
> +	struct list_head *plist = (struct list_head *)vaddr;
> +
> +	BUG_ON(!vaddr);
> +	BUG_ON(!ppool);
> +
> +	spin_lock_irqsave(&ppool->pool_lock, flags);
> +	list_add(plist, &ppool->pool_head);
> +	ppool->curr_count++;
> +	spin_unlock_irqrestore(&ppool->pool_lock, flags);

you should add logic to free resources here (or queue_work to free the
resources), if the pool grows beyond a certain size.



> +/**
> + * grow_resource_pool - grows the given resource pool
> + * @work - work struct
> + * This functions gets the resource pool pointer from the
> + * work struct and grows the resource pool by grow_count.
> + */
> +static void
> +grow_resource_pool(struct work_struct * work)
> +{
> +	struct resource_pool *ppool;
> +	struct list_head *plist;
> +	unsigned int min_count, grow_count = 0;
> +	unsigned long	flags;
> +
> +	ppool = container_of(work, struct resource_pool, work);
> +
> +	/* compute the minimum count to grow */
> +	spin_lock_irqsave(&ppool->pool_lock, flags);
> +	min_count = ppool->min_count + ppool->grow_count;
> +	if (ppool->curr_count < min_count)
> +		grow_count = min_count - ppool->curr_count;
> +	spin_unlock_irqrestore(&ppool->pool_lock, flags);
> +
> +	while(grow_count) {
> +		plist = (struct list_head *)ppool->alloc_mem(ppool->alloc_size,
> +			GFP_KERNEL);
> +
> +		if (!plist)
> +			break;
> +
> +		/* Add the element to the list */
> +		spin_lock_irqsave(&ppool->pool_lock, flags);
> +		list_add(plist, &ppool->pool_head);
> +		ppool->curr_count++;
> +		spin_unlock_irqrestore(&ppool->pool_lock, flags);
> +		grow_count--;
> +	}
> +}
> +
> +/**
> + * destroy_resource_pool - destroys the given resource pool
> + * @ppool - resource pool in question.
> + * This function walks throuhg its list and frees up the
> + * preallocated objects.
> + */
> +void
> +destroy_resource_pool(struct resource_pool *ppool)
> +{
> +	unsigned long	flags;
> +	struct list_head *plist;
> +
> +	spin_lock_irqsave(&ppool->pool_lock, flags);
> +	while (!list_empty(&ppool->pool_head)) {
> +		plist = &ppool->pool_head;
> +		list_del(plist);
> +
> +		ppool->free_mem(plist, ppool->alloc_size);
> +
> +	}
> +	ppool->curr_count = 0;
> +	spin_unlock_irqrestore(&ppool->pool_lock, flags);
> +}
> +
> +/**
> + * init_resource_pool - initializes the resource pool
> + * @res: resource pool in question.
> + * @min_count: count of objectes to pre-allocate
> + * @alloc_size: size of each objects
> + * @grow_count: count of objects to grow when required
> + * @alloc_fn: function which allocates memory
> + * @free_fn: function which frees memory
> + *
> + * This function initializes the given resource pool and
> + * populates the min_count of objects to begin with.
> + */
> +int
> +init_resource_pool(struct resource_pool *res,
> +	unsigned int min_count, unsigned int alloc_size,
> +	unsigned int grow_count, rpool_alloc_t alloc_fn,
> +	rpool_free_t free_fn)
> +{
> +	res->min_count = min_count;
> +	res->alloc_size = alloc_size;
> +	res->grow_count = grow_count;
> +	res->curr_count = 0;
> +	res->alloc_mem = alloc_fn;
> +	res->free_mem = free_fn;
> +	spin_lock_init(&res->pool_lock);
> +	INIT_LIST_HEAD(&res->pool_head);
> +	INIT_WORK(&res->work, grow_resource_pool);
> +
> +	/* grow the pool */
> +	grow_resource_pool(&res->work);
> +
> +	return (res->curr_count == 0);
> +}
> +
> 
> -- 
> -
> 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/

  reply	other threads:[~2007-06-04 22:57 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-04 21:02 [Intel-IOMMU 00/10] Intel IOMMU support anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 01/10] DMAR detection and parsing logic anil.s.keshavamurthy
2007-06-04 22:54   ` Jeff Garzik
2007-06-04 22:58     ` Keshavamurthy, Anil S
2007-06-04 23:03   ` Jeff Garzik
2007-06-04 23:17     ` Keshavamurthy, Anil S
2007-06-04 21:02 ` [Intel-IOMMU 02/10] Library routines for handling pre-allocated pool of objects anil.s.keshavamurthy
2007-06-04 22:57   ` Jeff Garzik [this message]
2007-06-04 23:06     ` Keshavamurthy, Anil S
2007-06-04 23:43       ` Jeff Garzik
2007-06-04 23:51         ` Keshavamurthy, Anil S
2007-06-05 20:24           ` Keshavamurthy, Anil S
2007-06-05 20:30             ` Jeff Garzik
2007-06-05 20:48               ` Keshavamurthy, Anil S
2007-06-04 21:02 ` [Intel-IOMMU 03/10] PCI generic helper function anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 04/10] clflush_cache_range now takes size param anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 05/10] IOVA allocation and management routines anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 06/10] Intel IOMMU driver anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 07/10] Intel iommu cmdline option - forcedac anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 08/10] DMAR fault handling support anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 09/10] Iommu Gfx workaround anil.s.keshavamurthy
2007-06-04 21:02 ` [Intel-IOMMU 10/10] Iommu floppy workaround anil.s.keshavamurthy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070604225714.GM20299@havoc.gtf.org \
    --to=jeff@garzik.org \
    --cc=ak@suse.de \
    --cc=akpm@osdl.org \
    --cc=anil.s.keshavamurthy@intel.com \
    --cc=arjan@linux.intel.com \
    --cc=ashok.raj@intel.com \
    --cc=asit.k.mallick@intel.com \
    --cc=davem@davemloft.net \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=muli@il.ibm.com \
    --cc=shaohua.li@intel.com \
    --cc=suresh.b.siddha@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®