Chelsio backport to 2.6.18 Signed-off-by: Steve Wise <[EMAIL PROTECTED]> ---
.../backport/2.6.18/include/linux/genalloc.h | 42 +++++ .../backport/2.6.18/include/linux/interrupt.h | 17 ++ .../backport/2.6.18/include/linux/netdevice.h | 9 + .../backport/2.6.18/include/linux/random.h | 15 ++ .../backport/2.6.18/include/linux/skbuff.h | 1 .../backport/2.6.18/include/linux/workqueue.h | 9 + .../backport/2.6.18/include/src/genalloc.c | 198 +++++++++++++++++++++++ .../backport/2.6.18/cxgb3_makefile_to_2_6_19.patch | 12 + .../backport/2.6.18/linux_genalloc_to_2_6_20.patch | 17 ++ 9 files changed, 319 insertions(+), 1 deletions(-) diff --git a/kernel_addons/backport/2.6.18/include/linux/genalloc.h b/kernel_addons/backport/2.6.18/include/linux/genalloc.h new file mode 100644 index 0000000..3c23c68 --- /dev/null +++ b/kernel_addons/backport/2.6.18/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.18/include/linux/interrupt.h b/kernel_addons/backport/2.6.18/include/linux/interrupt.h new file mode 100644 index 0000000..66e66a9 --- /dev/null +++ b/kernel_addons/backport/2.6.18/include/linux/interrupt.h @@ -0,0 +1,17 @@ +#ifndef BACKPORT_LINUX_INTERRUPT_TO_2_6_18 +#define BACKPORT_LINUX_INTERRUPT_TO_2_6_18 +#include_next <linux/interrupt.h> + +static inline int +backport_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *), + unsigned long flags, const char *dev_name, void *dev_id) +{ + return request_irq(irq, + (irqreturn_t (*)(int, void *, struct pt_regs *))handler, + flags, dev_name, dev_id); +} + +#define request_irq backport_request_irq + +#endif diff --git a/kernel_addons/backport/2.6.18/include/linux/netdevice.h b/kernel_addons/backport/2.6.18/include/linux/netdevice.h new file mode 100644 index 0000000..61a6deb --- /dev/null +++ b/kernel_addons/backport/2.6.18/include/linux/netdevice.h @@ -0,0 +1,9 @@ +#ifndef BACKPORT_LINUX_NETDEVICE_TO_2_6_18 +#define BACKPORT_LINUX_NETDEVICE_TO_2_6_18 +#include_next <linux/netdevice.h> + +#undef SET_ETHTOOL_OPS +#define SET_ETHTOOL_OPS(netdev, ops) \ + (netdev)->ethtool_ops = (struct ethtool_ops *)(ops) + +#endif diff --git a/kernel_addons/backport/2.6.18/include/linux/random.h b/kernel_addons/backport/2.6.18/include/linux/random.h new file mode 100644 index 0000000..2ea2e1f --- /dev/null +++ b/kernel_addons/backport/2.6.18/include/linux/random.h @@ -0,0 +1,15 @@ +#ifndef BACKPORT_LINUX_RANDOM_TO_2_6_18 +#define BACKPORT_LINUX_RANDOM_TO_2_6_18 +#include_next <linux/random.h> + +static inline u32 backport_random32(void) +{ + u32 v; + + get_random_bytes(&v, sizeof(u32)); + return v; +} + +#define random32 backport_random32 + +#endif diff --git a/kernel_addons/backport/2.6.18/include/linux/skbuff.h b/kernel_addons/backport/2.6.18/include/linux/skbuff.h index 4845283..ca5edc0 100644 --- a/kernel_addons/backport/2.6.18/include/linux/skbuff.h +++ b/kernel_addons/backport/2.6.18/include/linux/skbuff.h @@ -4,5 +4,6 @@ #define LINUX_SKBUFF_H_BACKPORT #include_next <linux/skbuff.h> #define CHECKSUM_PARTIAL CHECKSUM_HW +#define CHECKSUM_COMPLETE CHECKSUM_HW #endif diff --git a/kernel_addons/backport/2.6.18/include/linux/workqueue.h b/kernel_addons/backport/2.6.18/include/linux/workqueue.h index 330f47f..cc8b2cd 100644 --- a/kernel_addons/backport/2.6.18/include/linux/workqueue.h +++ b/kernel_addons/backport/2.6.18/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.18/include/src/genalloc.c b/kernel_addons/backport/2.6.18/include/src/genalloc.c new file mode 100644 index 0000000..75ae68c --- /dev/null +++ b/kernel_addons/backport/2.6.18/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 <[EMAIL PROTECTED]> + * + * 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.18/cxgb3_makefile_to_2_6_19.patch b/kernel_patches/backport/2.6.18/cxgb3_makefile_to_2_6_19.patch new file mode 100644 index 0000000..ad7e7f4 --- /dev/null +++ b/kernel_patches/backport/2.6.18/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.18/linux_genalloc_to_2_6_20.patch b/kernel_patches/backport/2.6.18/linux_genalloc_to_2_6_20.patch new file mode 100644 index 0000000..93fee2b --- /dev/null +++ b/kernel_patches/backport/2.6.18/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" _______________________________________________ openib-general mailing list openib-general@openib.org http://openib.org/mailman/listinfo/openib-general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general