All of lore.kernel.org
 help / color / mirror / Atom feed
From: Deepak Saxena <dsaxena@plexity.net>
To: torvalds@osdl.org, akpm@osdl.org
Cc: greg@kroah.com, linux-kernel@vger.kernel.org
Subject: [PATCH 2/3] Replace pci_pool with generic dma_pool
Date: Fri, 30 Jan 2004 17:39:37 -0700	[thread overview]
Message-ID: <20040131003937.GC24967@plexity.net> (raw)
In-Reply-To: <20040131003205.GA24967@plexity.net>

- Remove drivers/pci/pool.c
- Remove initialization of struct pci_dev.pools from pci_setup_device()


diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile	Fri Jan 30 12:20:30 2004
+++ b/drivers/pci/Makefile	Fri Jan 30 12:20:30 2004
@@ -2,7 +2,7 @@
 # Makefile for the PCI bus specific drivers.
 #
 
-obj-y		+= access.o bus.o probe.o remove.o pci.o pool.o quirks.o \
+obj-y		+= access.o bus.o probe.o remove.o pci.o quirks.o \
 			names.o pci-driver.o search.o pci-sysfs.o
 obj-$(CONFIG_PROC_FS) += proc.o
 
diff -Nru a/drivers/pci/pool.c b/drivers/pci/pool.c
--- a/drivers/pci/pool.c	Fri Jan 30 12:20:30 2004
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,404 +0,0 @@
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-/*
- * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
- * small blocks are easily used by drivers for bus mastering controllers.
- * This should probably be sharing the guts of the slab allocator.
- */
-
-struct pci_pool {	/* the pool */
-	struct list_head	page_list;
-	spinlock_t		lock;
-	size_t			blocks_per_page;
-	size_t			size;
-	struct pci_dev		*dev;
-	size_t			allocation;
-	char			name [32];
-	wait_queue_head_t	waitq;
-	struct list_head	pools;
-};
-
-struct pci_page {	/* cacheable header for 'allocation' bytes */
-	struct list_head	page_list;
-	void			*vaddr;
-	dma_addr_t		dma;
-	unsigned		in_use;
-	unsigned long		bitmap [0];
-};
-
-#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
-#define	POOL_POISON_FREED	0xa7	/* !inuse */
-#define	POOL_POISON_ALLOCATED	0xa9	/* !initted */
-
-static DECLARE_MUTEX (pools_lock);
-
-static ssize_t
-show_pools (struct device *dev, char *buf)
-{
-	struct pci_dev		*pdev;
-	unsigned		temp, size;
-	char			*next;
-	struct list_head	*i, *j;
-
-	pdev = container_of (dev, struct pci_dev, dev);
-	next = buf;
-	size = PAGE_SIZE;
-
-	temp = snprintf (next, size, "poolinfo - 0.1\n");
-	size -= temp;
-	next += temp;
-
-	down (&pools_lock);
-	list_for_each (i, &pdev->pools) {
-		struct pci_pool	*pool;
-		unsigned	pages = 0, blocks = 0;
-
-		pool = list_entry (i, struct pci_pool, pools);
-
-		list_for_each (j, &pool->page_list) {
-			struct pci_page	*page;
-
-			page = list_entry (j, struct pci_page, page_list);
-			pages++;
-			blocks += page->in_use;
-		}
-
-		/* per-pool info, no real statistics yet */
-		temp = snprintf (next, size, "%-16s %4u %4Zu %4Zu %2u\n",
-				pool->name,
-				blocks, pages * pool->blocks_per_page,
-				pool->size, pages);
-		size -= temp;
-		next += temp;
-	}
-	up (&pools_lock);
-
-	return PAGE_SIZE - size;
-}
-static DEVICE_ATTR (pools, S_IRUGO, show_pools, NULL);
-
-/**
- * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
- * @name: name of pool, for diagnostics
- * @pdev: pci device that will be doing the DMA
- * @size: size of the blocks in this pool.
- * @align: alignment requirement for blocks; must be a power of two
- * @allocation: returned blocks won't cross this boundary (or zero)
- * Context: !in_interrupt()
- *
- * Returns a pci allocation pool with the requested characteristics, or
- * null if one can't be created.  Given one of these pools, pci_pool_alloc()
- * may be used to allocate memory.  Such memory will all have "consistent"
- * DMA mappings, accessible by the device and its driver without using
- * cache flushing primitives.  The actual size of blocks allocated may be
- * larger than requested because of alignment.
- *
- * If allocation is nonzero, objects returned from pci_pool_alloc() won't
- * cross that size boundary.  This is useful for devices which have
- * addressing restrictions on individual DMA transfers, such as not crossing
- * boundaries of 4KBytes.
- */
-struct pci_pool *
-pci_pool_create (const char *name, struct pci_dev *pdev,
-	size_t size, size_t align, size_t allocation)
-{
-	struct pci_pool		*retval;
-
-	if (align == 0)
-		align = 1;
-	if (size == 0)
-		return 0;
-	else if (size < align)
-		size = align;
-	else if ((size % align) != 0) {
-		size += align + 1;
-		size &= ~(align - 1);
-	}
-
-	if (allocation == 0) {
-		if (PAGE_SIZE < size)
-			allocation = size;
-		else
-			allocation = PAGE_SIZE;
-		// FIXME: round up for less fragmentation
-	} else if (allocation < size)
-		return 0;
-
-	if (!(retval = kmalloc (sizeof *retval, SLAB_KERNEL)))
-		return retval;
-
-	strlcpy (retval->name, name, sizeof retval->name);
-
-	retval->dev = pdev;
-
-	INIT_LIST_HEAD (&retval->page_list);
-	spin_lock_init (&retval->lock);
-	retval->size = size;
-	retval->allocation = allocation;
-	retval->blocks_per_page = allocation / size;
-	init_waitqueue_head (&retval->waitq);
-
-	if (pdev) {
-		down (&pools_lock);
-		if (list_empty (&pdev->pools))
-			device_create_file (&pdev->dev, &dev_attr_pools);
-		/* note:  not currently insisting "name" be unique */
-		list_add (&retval->pools, &pdev->pools);
-		up (&pools_lock);
-	} else
-		INIT_LIST_HEAD (&retval->pools);
-
-	return retval;
-}
-
-
-static struct pci_page *
-pool_alloc_page (struct pci_pool *pool, int mem_flags)
-{
-	struct pci_page	*page;
-	int		mapsize;
-
-	mapsize = pool->blocks_per_page;
-	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
-	mapsize *= sizeof (long);
-
-	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
-	if (!page)
-		return 0;
-	page->vaddr = pci_alloc_consistent (pool->dev,
-					    pool->allocation,
-					    &page->dma);
-	if (page->vaddr) {
-		memset (page->bitmap, 0xff, mapsize);	// bit set == free
-#ifdef	CONFIG_DEBUG_SLAB
-		memset (page->vaddr, POOL_POISON_FREED, pool->allocation);
-#endif
-		list_add (&page->page_list, &pool->page_list);
-		page->in_use = 0;
-	} else {
-		kfree (page);
-		page = 0;
-	}
-	return page;
-}
-
-
-static inline int
-is_page_busy (int blocks, unsigned long *bitmap)
-{
-	while (blocks > 0) {
-		if (*bitmap++ != ~0UL)
-			return 1;
-		blocks -= BITS_PER_LONG;
-	}
-	return 0;
-}
-
-static void
-pool_free_page (struct pci_pool *pool, struct pci_page *page)
-{
-	dma_addr_t	dma = page->dma;
-
-#ifdef	CONFIG_DEBUG_SLAB
-	memset (page->vaddr, POOL_POISON_FREED, pool->allocation);
-#endif
-	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
-	list_del (&page->page_list);
-	kfree (page);
-}
-
-
-/**
- * pci_pool_destroy - destroys a pool of pci memory blocks.
- * @pool: pci pool that will be destroyed
- * Context: !in_interrupt()
- *
- * Caller guarantees that no more memory from the pool is in use,
- * and that nothing will try to use the pool after this call.
- */
-void
-pci_pool_destroy (struct pci_pool *pool)
-{
-	down (&pools_lock);
-	list_del (&pool->pools);
-	if (pool->dev && list_empty (&pool->dev->pools))
-		device_remove_file (&pool->dev->dev, &dev_attr_pools);
-	up (&pools_lock);
-
-	while (!list_empty (&pool->page_list)) {
-		struct pci_page		*page;
-		page = list_entry (pool->page_list.next,
-				struct pci_page, page_list);
-		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
-			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
-				pool->dev ? pci_name(pool->dev) : NULL,
-				pool->name, page->vaddr);
-			/* leak the still-in-use consistent memory */
-			list_del (&page->page_list);
-			kfree (page);
-		} else
-			pool_free_page (pool, page);
-	}
-
-	kfree (pool);
-}
-
-
-/**
- * pci_pool_alloc - get a block of consistent memory
- * @pool: pci pool that will produce the block
- * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
- * @handle: pointer to dma address of block
- *
- * This returns the kernel virtual address of a currently unused block,
- * and reports its dma address through the handle.
- * If such a memory block can't be allocated, null is returned.
- */
-void *
-pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-	int			map, block;
-	size_t			offset;
-	void			*retval;
-
-restart:
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		int		i;
-		page = list_entry (entry, struct pci_page, page_list);
-		/* only cachable accesses here ... */
-		for (map = 0, i = 0;
-				i < pool->blocks_per_page;
-				i += BITS_PER_LONG, map++) {
-			if (page->bitmap [map] == 0)
-				continue;
-			block = ffz (~ page->bitmap [map]);
-			if ((i + block) < pool->blocks_per_page) {
-				clear_bit (block, &page->bitmap [map]);
-				offset = (BITS_PER_LONG * map) + block;
-				offset *= pool->size;
-				goto ready;
-			}
-		}
-	}
-	if (!(page = pool_alloc_page (pool, SLAB_ATOMIC))) {
-		if (mem_flags == SLAB_KERNEL) {
-			DECLARE_WAITQUEUE (wait, current);
-
-			current->state = TASK_INTERRUPTIBLE;
-			add_wait_queue (&pool->waitq, &wait);
-			spin_unlock_irqrestore (&pool->lock, flags);
-
-			schedule_timeout (POOL_TIMEOUT_JIFFIES);
-
-			remove_wait_queue (&pool->waitq, &wait);
-			goto restart;
-		}
-		retval = 0;
-		goto done;
-	}
-
-	clear_bit (0, &page->bitmap [0]);
-	offset = 0;
-ready:
-	page->in_use++;
-	retval = offset + page->vaddr;
-	*handle = offset + page->dma;
-#ifdef	CONFIG_DEBUG_SLAB
-	memset (retval, POOL_POISON_ALLOCATED, pool->size);
-#endif
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return retval;
-}
-
-
-static struct pci_page *
-pool_find_page (struct pci_pool *pool, dma_addr_t dma)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		page = list_entry (entry, struct pci_page, page_list);
-		if (dma < page->dma)
-			continue;
-		if (dma < (page->dma + pool->allocation))
-			goto done;
-	}
-	page = 0;
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return page;
-}
-
-
-/**
- * pci_pool_free - put block back into pci pool
- * @pool: the pci pool holding the block
- * @vaddr: virtual address of block
- * @dma: dma address of block
- *
- * Caller promises neither device nor driver will again touch this block
- * unless it is first re-allocated.
- */
-void
-pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
-{
-	struct pci_page		*page;
-	unsigned long		flags;
-	int			map, block;
-
-	if ((page = pool_find_page (pool, dma)) == 0) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
-			pool->dev ? pci_name(pool->dev) : NULL,
-			pool->name, vaddr, (unsigned long) dma);
-		return;
-	}
-
-	block = dma - page->dma;
-	block /= pool->size;
-	map = block / BITS_PER_LONG;
-	block %= BITS_PER_LONG;
-
-#ifdef	CONFIG_DEBUG_SLAB
-	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%Lx\n",
-			pool->dev ? pci_name(pool->dev) : NULL,
-			pool->name, vaddr, (unsigned long long) dma);
-		return;
-	}
-	if (page->bitmap [map] & (1UL << block)) {
-		printk (KERN_ERR "pci_pool_free %s/%s, dma %Lx already free\n",
-			pool->dev ? pci_name(pool->dev) : NULL,
-			pool->name, (unsigned long long)dma);
-		return;
-	}
-	memset (vaddr, POOL_POISON_FREED, pool->size);
-#endif
-
-	spin_lock_irqsave (&pool->lock, flags);
-	page->in_use--;
-	set_bit (block, &page->bitmap [map]);
-	if (waitqueue_active (&pool->waitq))
-		wake_up (&pool->waitq);
-	/*
-	 * Resist a temptation to do
-	 *    if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
-	 * it is not interrupt safe. Better have empty pages hang around.
-	 */
-	spin_unlock_irqrestore (&pool->lock, flags);
-}
-
-
-EXPORT_SYMBOL (pci_pool_create);
-EXPORT_SYMBOL (pci_pool_destroy);
-EXPORT_SYMBOL (pci_pool_alloc);
-EXPORT_SYMBOL (pci_pool_free);
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c	Fri Jan 30 12:20:30 2004
+++ b/drivers/pci/probe.c	Fri Jan 30 12:20:30 2004
@@ -407,8 +407,6 @@
 	sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
 
-	INIT_LIST_HEAD(&dev->pools);
-
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
 	class >>= 8;				    /* upper 3 bytes */
 	dev->class = class;


-- 
Deepak Saxena - dsaxena@plexity.net

  parent reply	other threads:[~2004-01-31  0:40 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-31  0:32 [PATCH] Replace pci_pool with generic dma_pool Deepak Saxena
2004-01-31  0:37 ` [PATCH 1/3] " Deepak Saxena
2004-01-31  0:39 ` Deepak Saxena [this message]
2004-01-31  0:41 ` [PATCH 3/3] " Deepak Saxena
2004-01-31  1:05 ` [PATCH] " Greg KH
2004-02-02 19:02 ` Greg KH

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=20040131003937.GC24967@plexity.net \
    --to=dsaxena@plexity.net \
    --cc=akpm@osdl.org \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.