From: "Keshavamurthy, Anil S" <anil.s.keshavamurthy@intel.com>
To: Jeff Garzik <jeff@garzik.org>
Cc: anil.s.keshavamurthy@intel.com, 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 16:06:49 -0700 [thread overview]
Message-ID: <20070604230649.GB9948@linux-os.sc.intel.com> (raw)
In-Reply-To: <20070604225714.GM20299@havoc.gtf.org>
On Mon, Jun 04, 2007 at 06:57:14PM -0400, Jeff Garzik wrote:
> 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.
No, you got it wrong. This above function get_resource_pool_obj() itself
is called from interrrupt time so the logic is to get an object
from the pre-allocated pool if available else get it from kernel
without blocking which is to pass GFP_ATOMIC flag.
>
>
> > + 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.
Can be added as an add on, testing showed that pool
grows to a certain size and will not grow beyond that
as we tend to reuse the elements.
next prev parent reply other threads:[~2007-06-04 23:10 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
2007-06-04 23:06 ` Keshavamurthy, Anil S [this message]
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=20070604230649.GB9948@linux-os.sc.intel.com \
--to=anil.s.keshavamurthy@intel.com \
--cc=ak@suse.de \
--cc=akpm@osdl.org \
--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=jeff@garzik.org \
--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