[openib-general] [PATCH RFC 01/10] ofed_1_2 Chelsio backport to 2.6.19
Steve Wise
swise at opengridcomputing.com
Wed Jan 17 11:49:51 PST 2007
Chelsio backport to 2.6.19
Signed-off-by: Steve Wise <swise at opengridcomputing.com>
---
.../backport/2.6.19/include/linux/genalloc.h | 42 +++++
.../backport/2.6.19/include/linux/workqueue.h | 9 +
.../backport/2.6.19/include/src/genalloc.c | 198 +++++++++++++++++++++++
.../backport/2.6.19/cxgb3_makefile_to_2_6_19.patch | 12 +
.../backport/2.6.19/linux_genalloc_to_2_6_20.patch | 17 ++
5 files changed, 277 insertions(+), 1 deletions(-)
diff --git a/kernel_addons/backport/2.6.19/include/linux/genalloc.h b/kernel_addons/backport/2.6.19/include/linux/genalloc.h
new file mode 100644
index 0000000..3c23c68
--- /dev/null
+++ b/kernel_addons/backport/2.6.19/include/linux/genalloc.h
@@ -0,0 +1,42 @@
+/*
+ * Basic general purpose allocator for managing special purpose memory
+ * not managed by the regular kmalloc/kfree interface.
+ * Uses for this includes on-device special memory, uncached memory
+ * etc.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+
+/*
+ * General purpose special memory pool descriptor.
+ */
+struct gen_pool {
+ rwlock_t lock;
+ struct list_head chunks; /* list of chunks in this pool */
+ int min_alloc_order; /* minimum allocation order */
+};
+
+/*
+ * General purpose special memory pool chunk descriptor.
+ */
+struct gen_pool_chunk {
+ spinlock_t lock;
+ struct list_head next_chunk; /* next chunk in pool */
+ unsigned long start_addr; /* starting address of memory chunk */
+ unsigned long end_addr; /* ending address of memory chunk */
+ unsigned long bits[0]; /* bitmap for allocating memory chunk */
+};
+
+extern struct gen_pool *ib_gen_pool_create(int, int);
+extern int ib_gen_pool_add(struct gen_pool *, unsigned long, size_t, int);
+extern void ib_gen_pool_destroy(struct gen_pool *);
+extern unsigned long ib_gen_pool_alloc(struct gen_pool *, size_t);
+extern void ib_gen_pool_free(struct gen_pool *, unsigned long, size_t);
+
+#define gen_pool_create ib_gen_pool_create
+#define gen_pool_add ib_gen_pool_add
+#define gen_pool_destroy ib_gen_pool_destroy
+#define gen_pool_alloc ib_gen_pool_alloc
+#define gen_pool_free ib_gen_pool_free
diff --git a/kernel_addons/backport/2.6.19/include/linux/workqueue.h b/kernel_addons/backport/2.6.19/include/linux/workqueue.h
index 330f47f..cc8b2cd 100644
--- a/kernel_addons/backport/2.6.19/include/linux/workqueue.h
+++ b/kernel_addons/backport/2.6.19/include/linux/workqueue.h
@@ -26,6 +26,12 @@ backport_cancel_delayed_work(struct dela
return cancel_delayed_work(&work->work);
}
+static inline void
+backport_cancel_rearming_delayed_workqueue(struct workqueue_struct *wq, struct delayed_work *work)
+{
+ cancel_rearming_delayed_workqueue(wq, &work->work);
+}
+
#undef INIT_WORK
#define INIT_WORK(_work, _func) backport_INIT_WORK(_work, _func)
@@ -33,11 +39,12 @@ #define INIT_DELAYED_WORK(_work, _func)
#undef DECLARE_WORK
#define DECLARE_WORK(n, f) \
- struct work_struct n = __WORK_INITIALIZER(n, f, &(n))
+ struct work_struct n = __WORK_INITIALIZER(n, (void (*)(void *))f, &(n))
#define DECLARE_DELAYED_WORK(n, f) \
struct delayed_work n = { .work = __WORK_INITIALIZER(n.work, f, &(n.work)) }
#define queue_delayed_work backport_queue_delayed_work
#define cancel_delayed_work backport_cancel_delayed_work
+#define cancel_rearming_delayed_workqueue backport_cancel_rearming_delayed_workqueue
#endif
diff --git a/kernel_addons/backport/2.6.19/include/src/genalloc.c b/kernel_addons/backport/2.6.19/include/src/genalloc.c
new file mode 100644
index 0000000..75ae68c
--- /dev/null
+++ b/kernel_addons/backport/2.6.19/include/src/genalloc.c
@@ -0,0 +1,198 @@
+/*
+ * Basic general purpose allocator for managing special purpose memory
+ * not managed by the regular kmalloc/kfree interface.
+ * Uses for this includes on-device special memory, uncached memory
+ * etc.
+ *
+ * Copyright 2005 (C) Jes Sorensen <jes at trained-monkey.org>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/genalloc.h>
+
+
+/**
+ * gen_pool_create - create a new special memory pool
+ * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents
+ * @nid: node id of the node the pool structure should be allocated on, or -1
+ *
+ * Create a new special memory pool that can be used to manage special purpose
+ * memory not managed by the regular kmalloc/kfree interface.
+ */
+struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
+{
+ struct gen_pool *pool;
+
+ pool = kmalloc_node(sizeof(struct gen_pool), GFP_KERNEL, nid);
+ if (pool != NULL) {
+ rwlock_init(&pool->lock);
+ INIT_LIST_HEAD(&pool->chunks);
+ pool->min_alloc_order = min_alloc_order;
+ }
+ return pool;
+}
+EXPORT_SYMBOL(gen_pool_create);
+
+/**
+ * gen_pool_add - add a new chunk of special memory to the pool
+ * @pool: pool to add new memory chunk to
+ * @addr: starting address of memory chunk to add to pool
+ * @size: size in bytes of the memory chunk to add to pool
+ * @nid: node id of the node the chunk structure and bitmap should be
+ * allocated on, or -1
+ *
+ * Add a new chunk of special memory to the specified pool.
+ */
+int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
+ int nid)
+{
+ struct gen_pool_chunk *chunk;
+ int nbits = size >> pool->min_alloc_order;
+ int nbytes = sizeof(struct gen_pool_chunk) +
+ (nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
+
+ chunk = kmalloc_node(nbytes, GFP_KERNEL, nid);
+ if (unlikely(chunk == NULL))
+ return -1;
+
+ memset(chunk, 0, nbytes);
+ spin_lock_init(&chunk->lock);
+ chunk->start_addr = addr;
+ chunk->end_addr = addr + size;
+
+ write_lock(&pool->lock);
+ list_add(&chunk->next_chunk, &pool->chunks);
+ write_unlock(&pool->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(gen_pool_add);
+
+/**
+ * gen_pool_destroy - destroy a special memory pool
+ * @pool: pool to destroy
+ *
+ * Destroy the specified special memory pool. Verifies that there are no
+ * outstanding allocations.
+ */
+void gen_pool_destroy(struct gen_pool *pool)
+{
+ struct list_head *_chunk, *_next_chunk;
+ struct gen_pool_chunk *chunk;
+ int order = pool->min_alloc_order;
+ int bit, end_bit;
+
+
+ write_lock(&pool->lock);
+ list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
+ chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+ list_del(&chunk->next_chunk);
+
+ end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+ bit = find_next_bit(chunk->bits, end_bit, 0);
+ BUG_ON(bit < end_bit);
+
+ kfree(chunk);
+ }
+ kfree(pool);
+ return;
+}
+EXPORT_SYMBOL(gen_pool_destroy);
+
+/**
+ * gen_pool_alloc - allocate special memory from the pool
+ * @pool: pool to allocate from
+ * @size: number of bytes to allocate from the pool
+ *
+ * Allocate the requested number of bytes from the specified pool.
+ * Uses a first-fit algorithm.
+ */
+unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
+{
+ struct list_head *_chunk;
+ struct gen_pool_chunk *chunk;
+ unsigned long addr, flags;
+ int order = pool->min_alloc_order;
+ int nbits, bit, start_bit, end_bit;
+
+ if (size == 0)
+ return 0;
+
+ nbits = (size + (1UL << order) - 1) >> order;
+
+ read_lock(&pool->lock);
+ list_for_each(_chunk, &pool->chunks) {
+ chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+
+ end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+ end_bit -= nbits + 1;
+
+ spin_lock_irqsave(&chunk->lock, flags);
+ bit = -1;
+ while (bit + 1 < end_bit) {
+ bit = find_next_zero_bit(chunk->bits, end_bit, bit + 1);
+ if (bit >= end_bit)
+ break;
+
+ start_bit = bit;
+ if (nbits > 1) {
+ bit = find_next_bit(chunk->bits, bit + nbits,
+ bit + 1);
+ if (bit - start_bit < nbits)
+ continue;
+ }
+
+ addr = chunk->start_addr +
+ ((unsigned long)start_bit << order);
+ while (nbits--)
+ __set_bit(start_bit++, &chunk->bits);
+ spin_unlock_irqrestore(&chunk->lock, flags);
+ read_unlock(&pool->lock);
+ return addr;
+ }
+ spin_unlock_irqrestore(&chunk->lock, flags);
+ }
+ read_unlock(&pool->lock);
+ return 0;
+}
+EXPORT_SYMBOL(gen_pool_alloc);
+
+/**
+ * gen_pool_free - free allocated special memory back to the pool
+ * @pool: pool to free to
+ * @addr: starting address of memory to free back to pool
+ * @size: size in bytes of memory to free
+ *
+ * Free previously allocated special memory back to the specified pool.
+ */
+void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
+{
+ struct list_head *_chunk;
+ struct gen_pool_chunk *chunk;
+ unsigned long flags;
+ int order = pool->min_alloc_order;
+ int bit, nbits;
+
+ nbits = (size + (1UL << order) - 1) >> order;
+
+ read_lock(&pool->lock);
+ list_for_each(_chunk, &pool->chunks) {
+ chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+
+ if (addr >= chunk->start_addr && addr < chunk->end_addr) {
+ BUG_ON(addr + size > chunk->end_addr);
+ spin_lock_irqsave(&chunk->lock, flags);
+ bit = (addr - chunk->start_addr) >> order;
+ while (nbits--)
+ __clear_bit(bit++, &chunk->bits);
+ spin_unlock_irqrestore(&chunk->lock, flags);
+ break;
+ }
+ }
+ BUG_ON(nbits > 0);
+ read_unlock(&pool->lock);
+}
+EXPORT_SYMBOL(gen_pool_free);
diff --git a/kernel_patches/backport/2.6.19/cxgb3_makefile_to_2_6_19.patch b/kernel_patches/backport/2.6.19/cxgb3_makefile_to_2_6_19.patch
new file mode 100644
index 0000000..ad7e7f4
--- /dev/null
+++ b/kernel_patches/backport/2.6.19/cxgb3_makefile_to_2_6_19.patch
@@ -0,0 +1,12 @@
+diff --git a/drivers/net/cxgb3/Makefile b/drivers/net/cxgb3/Makefile
+index 3434679..bb008b6 100755
+--- a/drivers/net/cxgb3/Makefile
++++ b/drivers/net/cxgb3/Makefile
+@@ -1,6 +1,7 @@
+ #
+ # Chelsio T3 driver
+ #
++NOSTDINC_FLAGS:= $(NOSTDINC_FLAGS) $(LINUXINCLUDE)
+
+ obj-$(CONFIG_CHELSIO_T3) += cxgb3.o
+
diff --git a/kernel_patches/backport/2.6.19/linux_genalloc_to_2_6_20.patch b/kernel_patches/backport/2.6.19/linux_genalloc_to_2_6_20.patch
new file mode 100644
index 0000000..93fee2b
--- /dev/null
+++ b/kernel_patches/backport/2.6.19/linux_genalloc_to_2_6_20.patch
@@ -0,0 +1,17 @@
+diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
+index 163d991..2cd239f 100644
+--- a/drivers/infiniband/core/Makefile
++++ b/drivers/infiniband/core/Makefile
+@@ -30,3 +30,5 @@ ib_ucm-y := ucm.o
+
+ ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_mem.o \
+ uverbs_marshall.o
++
++ib_core-y += genalloc.o
+diff --git a/drivers/infiniband/core/genalloc.c b/drivers/infiniband/core/genalloc.c
+new file mode 100644
+index 0000000..96a48fe
+--- /dev/null
++++ b/drivers/infiniband/core/genalloc.c
+@@ -0,0 +1 @@
++#include "src/genalloc.c"
More information about the general
mailing list