From owner-svn-src-projects@FreeBSD.ORG Sun Jun 13 07:30:52 2010 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AF5C4106564A; Sun, 13 Jun 2010 07:30:52 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9CBB38FC12; Sun, 13 Jun 2010 07:30:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o5D7UqF6050312; Sun, 13 Jun 2010 07:30:52 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o5D7UqYS050291; Sun, 13 Jun 2010 07:30:52 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201006130730.o5D7UqYS050291@svn.freebsd.org> From: Jeff Roberson Date: Sun, 13 Jun 2010 07:30:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r209121 - in projects/ofed/head/sys/ofed/include: asm linux net X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Jun 2010 07:30:52 -0000 Author: jeff Date: Sun Jun 13 07:30:51 2010 New Revision: 209121 URL: http://svn.freebsd.org/changeset/base/209121 Log: - Redefine net_device to ifnet. They are close enough to use interchangeably. - Create a linux_file wrapper around bsd files and define a thunking layer between them. - Add a radix tree implementation for idr. It uses a per-idr lock and never shrinks trees but should perform well enough. - Expand other miscellaneous wrappers. - Remove Linux's net/route so bsd's is included instead. No attempt will be made to wrap the linux route implementation as it differs too greatly from our own. Sponsored by: Isilon Systems, iX Systems, and Panasas. Added: projects/ofed/head/sys/ofed/include/linux/linux_compat.c projects/ofed/head/sys/ofed/include/linux/linux_idr.c projects/ofed/head/sys/ofed/include/linux/net.h projects/ofed/head/sys/ofed/include/net/ip.h Deleted: projects/ofed/head/sys/ofed/include/net/route.h Modified: projects/ofed/head/sys/ofed/include/asm/atomic-long.h projects/ofed/head/sys/ofed/include/asm/uaccess.h projects/ofed/head/sys/ofed/include/linux/bitops.h projects/ofed/head/sys/ofed/include/linux/cdev.h projects/ofed/head/sys/ofed/include/linux/completion.h projects/ofed/head/sys/ofed/include/linux/ethtool.h projects/ofed/head/sys/ofed/include/linux/file.h projects/ofed/head/sys/ofed/include/linux/fs.h projects/ofed/head/sys/ofed/include/linux/idr.h projects/ofed/head/sys/ofed/include/linux/inetdevice.h projects/ofed/head/sys/ofed/include/linux/jiffies.h projects/ofed/head/sys/ofed/include/linux/kobject.h projects/ofed/head/sys/ofed/include/linux/list.h projects/ofed/head/sys/ofed/include/linux/lockdep.h projects/ofed/head/sys/ofed/include/linux/miscdevice.h projects/ofed/head/sys/ofed/include/linux/netdevice.h projects/ofed/head/sys/ofed/include/linux/rbtree.h projects/ofed/head/sys/ofed/include/linux/wait.h projects/ofed/head/sys/ofed/include/net/tcp.h Modified: projects/ofed/head/sys/ofed/include/asm/atomic-long.h ============================================================================== --- projects/ofed/head/sys/ofed/include/asm/atomic-long.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/asm/atomic-long.h Sun Jun 13 07:30:51 2010 (r209121) @@ -1,4 +1,4 @@ -*- +/*- * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. @@ -69,7 +69,7 @@ atomic_long_dec(atomic_long_t *v) return atomic_fetchadd_long(&v->counter, -1) - 1; } -static inline__ long +static inline long atomic_long_dec_and_test(atomic_long_t *v) { long i = atomic_long_add(-1, v); Modified: projects/ofed/head/sys/ofed/include/asm/uaccess.h ============================================================================== --- projects/ofed/head/sys/ofed/include/asm/uaccess.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/asm/uaccess.h Sun Jun 13 07:30:51 2010 (r209121) @@ -25,12 +25,25 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _LINUX_UACCESS_H_ -#define _LINUX_UACCESS_H_ +#ifndef _ASM_UACCESS_H_ +#define _ASM_UACCESS_H_ #include -long copy_from_user(void *to, const void __user * from, unsigned long n); -long copy_to_user(void __user *to, const void *from, unsigned long n); +static inline long +copy_to_user(void *to, const void *from, unsigned long n) +{ + if (copyout(from, to, n) != 0) + return n; + return 0; +} -#endif /* _LINUX_UACCESS_H_ */ +static inline long +copy_from_user(void *to, const void *from, unsigned long n) +{ + if (copyin(from, to, n) != 0) + return n; + return 0; +} + +#endif /* _ASM_UACCESS_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/bitops.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/bitops.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/bitops.h Sun Jun 13 07:30:51 2010 (r209121) @@ -32,6 +32,18 @@ #define BIT_MASK(n) (~0UL >> (BITS_PER_LONG - (n))) #define BITS_TO_LONGS(n) roundup2((n), BITS_PER_LONG) +static inline int +__ffsl(long mask) +{ + return (ffsl(mask) - 1); +} + +static inline int +__flsl(long mask) +{ + return (flsl(mask) - 1); +} + static inline unsigned long find_first_bit(unsigned long *addr, unsigned long size) { @@ -42,12 +54,12 @@ find_first_bit(unsigned long *addr, unsi size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) { if (*addr == 0) continue; - return (bit + ffs(*addr)); + return (bit + __ffsl(*addr)); } if (size) { mask = (*addr) & BIT_MASK(size); if (mask) - bit += ffsl(mask); + bit += __ffsl(mask); else bit += size; } @@ -64,12 +76,12 @@ find_first_zero_bit(unsigned long *addr, size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) { if (~(*addr) == 0) continue; - return (bit + ffs(~(*addr))); + return (bit + __ffsl(~(*addr))); } if (size) { mask = ~(*addr) & BIT_MASK(size); if (mask) - bit += ffsl(mask); + bit += __ffsl(mask); else bit += size; } @@ -91,13 +103,13 @@ find_last_bit(unsigned long *addr, unsig if (offs) { mask = (*addr) & BIT_MASK(offs); if (mask) - return (bit + flsl(mask)); + return (bit + __flsl(mask)); } while (--pos) { addr--; bit -= BITS_PER_LONG; if (*addr) - return (bit + flsl(mask)); + return (bit + __flsl(mask)); } return (size); } @@ -117,7 +129,7 @@ find_next_bit(unsigned long *addr, unsig if (offs) { mask = (*addr) & ~BIT_MASK(offs); if (mask) - return (bit + ffsl(mask)); + return (bit + __ffsl(mask)); bit += BITS_PER_LONG; addr++; } @@ -125,12 +137,12 @@ find_next_bit(unsigned long *addr, unsig size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) { if (*addr == 0) continue; - return (bit + ffs(*addr)); + return (bit + __ffsl(*addr)); } if (size) { mask = (*addr) & BIT_MASK(size); if (mask) - bit += ffsl(mask); + bit += __ffsl(mask); else bit += size; } Modified: projects/ofed/head/sys/ofed/include/linux/cdev.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/cdev.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/cdev.h Sun Jun 13 07:30:51 2010 (r209121) @@ -46,10 +46,31 @@ struct cdev { const struct file_operations *ops; }; -void cdev_init(struct cdev *, const struct file_operations *); -struct cdev *cdev_alloc(void); -void cdev_put(struct cdev *p); -int cdev_add(struct cdev *, dev_t, unsigned); -void cdev_del(struct cdev *); +static inline void +cdev_init(struct cdev *cdev, const struct file_operations *ops) +{ +} + +static inline struct cdev * +cdev_alloc(void) +{ + return (NULL); +} + +static inline void +cdev_put(struct cdev *p) +{ +} + +static inline int +cdev_add(struct cdev *cdev, dev_t dev, unsigned count) +{ + return (0); +} + +static inline void +cdev_del(struct cdev *cdev) +{ +} #endif /* _LINUX_CDEV_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/completion.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/completion.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/completion.h Sun Jun 13 07:30:51 2010 (r209121) @@ -30,6 +30,7 @@ #include #include +#include #include #include Modified: projects/ofed/head/sys/ofed/include/linux/ethtool.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/ethtool.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/ethtool.h Sun Jun 13 07:30:51 2010 (r209121) @@ -28,16 +28,4 @@ #ifndef _LINUX_ETHTOOL_H_ #define _LINUX_ETHTOOL_H_ -#include - -struct net_device; - -struct ethtool_cmd { - u16 speed; -}; - -struct ethtool_ops { - int (*get_settings)(struct net_device *, struct ethtool_cmd *); -}; - #endif /* _LINUX_ETHTOOL_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/file.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/file.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/file.h Sun Jun 13 07:30:51 2010 (r209121) @@ -30,28 +30,49 @@ #include -struct file; +struct linux_file; -static inline struct file * -fget(unsigned int fd) +#undef file + +struct fileops linuxfileops; + +static inline struct linux_file * +linux_fget(unsigned int fd) { + struct file *file; - return (NULL); + file = fget_unlocked(curthread->td_proc->p_fd, fd); + return (struct linux_file *)file->f_data; } static inline void -fput(struct file *filp) +fput(struct linux_file *filp) { + if (refcount_release(&filp->_file->f_count)) { + _fdrop(filp->_file, curthread); + kfree(filp); + } } static inline void put_unused_fd(unsigned int fd) { + struct linux_file *file; + + file = linux_fget(fd); + if (file == NULL) + return; + if (file->_file) + fdclose(curthread->td_proc->p_fd, file->_file, fd, curthread); } static inline void fd_install(unsigned int fd, struct file *file) { + file->f_ops = &linuxfileops; } +#define file linux_file +#define fget linux_fget + #endif /* _LINUX_FILE_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/fs.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/fs.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/fs.h Sun Jun 13 07:30:51 2010 (r209121) @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include @@ -57,13 +59,19 @@ struct dentry { struct inode *d_inode; }; -struct file { - void *private_data; - int f_flags; - struct dentry *f_dentry; - struct dentry f_dentry_store; +struct file_operations; + +struct linux_file { + struct file *_file; + struct file_operations *f_op; + void *private_data; + int f_flags; + struct dentry *f_dentry; + struct dentry f_dentry_store; }; +#define file linux_file + typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned); struct file_operations { Modified: projects/ofed/head/sys/ofed/include/linux/idr.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/idr.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/idr.h Sun Jun 13 07:30:51 2010 (r209121) @@ -29,34 +29,33 @@ #ifndef _LINUX_IDR_H_ #define _LINUX_IDR_H_ -#if defined(__LP64__) -#define IDR_BITS 5 -#define IDR_FULL 0xfffffffful -#else -#define IDR_BITS 6 -#define IDR_FULL 0xfffffffffffffffful -#endif - +#define IDR_BITS 5 #define IDR_SIZE (1 << IDR_BITS) -#define IDR_MASK ((1 << IDR_BITS) - 1) +#define IDR_MASK (IDR_SIZE - 1) -#define MAX_ID_SHIFT (sizeof(int) * 8 - 1) +#define MAX_ID_SHIFT ((sizeof(int) * NBBY) - 1) #define MAX_ID_BIT (1U << MAX_ID_SHIFT) #define MAX_ID_MASK (MAX_ID_BIT - 1) +#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS + +struct idr_layer { + unsigned long bitmap; + struct idr_layer *ary[IDR_SIZE]; +}; struct idr { + struct idr_layer *top; + struct idr_layer *free; + int layers; + struct mtx lock; }; -#define IDR_INIT(name) (name) = {} #define DEFINE_IDR(name) struct idr name void *idr_find(struct idr *idp, int id); int idr_pre_get(struct idr *idp, gfp_t gfp_mask); int idr_get_new(struct idr *idp, void *ptr, int *id); int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); -int idr_for_each(struct idr *idp, int (*fn)(int id, void *p, void *data), - void *data); -void *idr_get_next(struct idr *idp, int *nextid); void *idr_replace(struct idr *idp, void *ptr, int id); void idr_remove(struct idr *idp, int id); void idr_remove_all(struct idr *idp); Modified: projects/ofed/head/sys/ofed/include/linux/inetdevice.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/inetdevice.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/inetdevice.h Sun Jun 13 07:30:51 2010 (r209121) @@ -31,4 +31,24 @@ #include +static inline struct net_device * +ip_dev_find(struct net *net, uint32_t addr) +{ + struct sockaddr_in sin; + struct ifaddr *ifa; + struct ifnet *ifp; + + ifp = NULL; + sin.sin_addr.s_addr = addr; + sin.sin_port = 0; + sin.sin_len = sizeof(sin); + ifa = ifa_ifwithaddr((struct sockaddr *)&sin); + if (ifa) { + ifp = ifa->ifa_ifp; + if_ref(ifp); + ifa_free(ifa); + } + return (ifp); +} + #endif /* _LINUX_INETDEVICE_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/jiffies.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/jiffies.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/jiffies.h Sun Jun 13 07:30:51 2010 (r209121) @@ -45,6 +45,8 @@ msecs_to_jiffies(int msec) #define time_after(a, b) ((long)(b) - (long)(a) < 0) #define time_before(a, b) time_after(b,a) +#define time_after_eq(a, b) ((long)(a) - (long)(b) >= 0) +#define time_before_eq(a, b) time_after_eq(b, a) #endif /* _LINUX_JIFFIES_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/kobject.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/kobject.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/kobject.h Sun Jun 13 07:30:51 2010 (r209121) @@ -47,7 +47,6 @@ struct kobject { struct kobj_type *ktype; }; - static inline int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, struct kobject *parent, const char *fmt, ...) @@ -97,20 +96,6 @@ kobject_set_name_vargs(struct kobject *k return (0); } - -static inline int -kobject_set_name(struct kobject *kobj, const char *fmt, ...) -{ - va_list args; - int error; - - va_start(args, fmt); - error = kobject_set_name_vargs(kobj, fmt, args); - va_end(args); - - return (error); -} - static inline int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...) { @@ -132,4 +117,6 @@ kobject_name(const struct kobject *kobj) return kobj->name; } +int kobject_set_name(struct kobject *kobj, const char *fmt, ...); + #endif /* _LINUX_KOBJECT_H_ */ Added: projects/ofed/head/sys/ofed/include/linux/linux_compat.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/ofed/head/sys/ofed/include/linux/linux_compat.c Sun Jun 13 07:30:51 2010 (r209121) @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +MALLOC_DEFINE(M_KMALLOC, "linux", "Linux kmalloc compat"); + +#include +/* Undo Linux compat change. */ +#undef RB_ROOT +#define RB_ROOT(head) (head)->rbh_root + +int +panic_cmp(struct rb_node *one, struct rb_node *two) +{ + panic("no cmp"); +} + +RB_GENERATE(linux_root, rb_node, __entry, panic_cmp); + +int +kobject_set_name(struct kobject *kobj, const char *fmt, ...) +{ + va_list args; + int error; + + va_start(args, fmt); + error = kobject_set_name_vargs(kobj, fmt, args); + va_end(args); + + return (error); +} Added: projects/ofed/head/sys/ofed/include/linux/linux_idr.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/ofed/head/sys/ofed/include/linux/linux_idr.c Sun Jun 13 07:30:51 2010 (r209121) @@ -0,0 +1,427 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +/* + * IDR Implementation. + * + * This is quick and dirty and not as re-entrant as the linux version + * however it should be fairly fast. It is basically a radix tree with + * a builtin bitmap for allocation. + */ +MALLOC_DEFINE(M_IDR, "idr", "Linux IDR compat"); + +static inline int +idr_max(struct idr *idr) +{ + return (1 << (idr->layers * IDR_BITS)) - 1; +} + +static inline int +idr_pos(int id, int layer) +{ + return (id >> (IDR_BITS * layer)) & IDR_MASK; +} + +void +idr_init(struct idr *idr) +{ + bzero(idr, sizeof(*idr)); + mtx_init(&idr->lock, "idr", NULL, MTX_DEF); +} + +/* Only frees cached pages. */ +void +idr_destroy(struct idr *idr) +{ + struct idr_layer *il, *iln; + + mtx_lock(&idr->lock); + for (il = idr->free; il != NULL; il = iln) { + iln = il->ary[0]; + free(il, M_IDR); + } + mtx_unlock(&idr->lock); +} + +static void +idr_remove_layer(struct idr_layer *il, int layer) +{ + int i; + + if (il == NULL) + return; + if (layer == 0) { + free(il, M_IDR); + return; + } + for (i = 0; i < IDR_SIZE; i++) + if (il->ary[i]) + idr_remove_layer(il->ary[i], layer - 1); +} + +void +idr_remove_all(struct idr *idr) +{ + + mtx_lock(&idr->lock); + idr_remove_layer(idr->top, idr->layers - 1); + idr->top = NULL; + idr->layers = 0; + mtx_unlock(&idr->lock); +} + +void +idr_remove(struct idr *idr, int id) +{ + struct idr_layer *il; + int layer; + int idx; + + id &= MAX_ID_MASK; + mtx_lock(&idr->lock); + il = idr->top; + layer = idr->layers - 1; + if (il == NULL || id > idr_max(idr)) { + mtx_unlock(&idr->lock); + return; + } + /* + * Walk down the tree to this item setting bitmaps along the way + * as we know at least one item will be free along this path. + */ + while (layer && il) { + idx = idr_pos(id, layer); + il->bitmap |= 1 << idx; + il = il->ary[idx]; + layer--; + } + idx = id & IDR_MASK; + /* + * At this point we've set free space bitmaps up the whole tree. + * We could make this non-fatal and unwind but linux dumps a stack + * and a warning so I don't think it's necessary. + */ + if (il == NULL || (il->bitmap & (1 << idx)) == 0) + panic("idr_remove: Item %d not allocated (%p, %p)\n", + id, idr, il); + il->ary[idx] = NULL; + mtx_unlock(&idr->lock); + return; +} + +void * +idr_replace(struct idr *idr, void *ptr, int id) +{ + struct idr_layer *il; + void *res; + int layer; + int idx; + + res = ERR_PTR(-EINVAL); + id &= MAX_ID_MASK; + mtx_lock(&idr->lock); + il = idr->top; + layer = idr->layers - 1; + if (il == NULL || id > idr_max(idr)) + goto out; + while (layer && il) { + il = il->ary[idr_pos(id, layer)]; + layer--; + } + idx = id & IDR_MASK; + /* + * Replace still returns an error if the item was not allocated. + */ + if (il != NULL && (il->bitmap & (1 << idx)) == 0) { + res = il->ary[idx]; + il->ary[idx] = ptr; + } +out: + mtx_unlock(&idr->lock); + return (res); +} + +void * +idr_find(struct idr *idr, int id) +{ + struct idr_layer *il; + void *res; + int layer; + + res = NULL; + id &= MAX_ID_MASK; + mtx_lock(&idr->lock); + il = idr->top; + layer = idr->layers - 1; + if (il == NULL || id > idr_max(idr)) + goto out; + while (layer && il) { + il = il->ary[idr_pos(id, layer)]; + layer--; + } + if (il != NULL) + res = il->ary[id & IDR_MASK]; +out: + mtx_unlock(&idr->lock); + return (res); +} + +int +idr_pre_get(struct idr *idr, gfp_t gfp_mask) +{ + struct idr_layer *il, *iln; + struct idr_layer *head; + int need; + + mtx_lock(&idr->lock); + for (;;) { + need = idr->layers + 1; + for (il = idr->free; il != NULL; il = il->ary[0]) + need--; + mtx_unlock(&idr->lock); + if (need == 0) + break; + for (head = NULL; need; need--) { + iln = malloc(sizeof(*il), M_IDR, M_ZERO | gfp_mask); + if (iln == NULL) + break; + iln->bitmap = IDR_MASK; + if (head != NULL) { + il->ary[0] = iln; + il = iln; + } else + head = il = iln; + } + if (head == NULL) + return (0); + mtx_lock(&idr->lock); + il->ary[0] = idr->free; + idr->free = head; + } + return (1); +} + +static inline struct idr_layer * +idr_get(struct idr *idr) +{ + struct idr_layer *il; + + il = idr->free; + if (il) { + idr->free = il->ary[0]; + il->ary[0] = NULL; + return (il); + } + il = malloc(sizeof(*il), M_IDR, M_ZERO | M_NOWAIT); + return (il); +} + +/* + * Could be implemented as get_new_above(idr, ptr, 0, idp) but written + * first for simplicity sake. + */ +int +idr_get_new(struct idr *idr, void *ptr, int *idp) +{ + struct idr_layer *stack[MAX_LEVEL]; + struct idr_layer *il; + int error; + int layer; + int idx; + int id; + + error = -EAGAIN; + mtx_lock(&idr->lock); + /* + * Expand the tree until there is free space. + */ + if (idr->top == NULL || idr->top->bitmap == 0) { + if (idr->layers == MAX_LEVEL + 1) { + error = -ENOSPC; + goto out; + } + il = idr_get(idr); + if (il == NULL) + goto out; + il->ary[0] = idr->top; + if (idr->top) + il->bitmap &= ~1; + idr->top = il; + idr->layers++; + } + il = idr->top; + id = 0; + /* + * Walk the tree following free bitmaps, record our path. + */ + for (layer = idr->layers - 1;; layer--) { + stack[layer] = il; + idx = ffsl(il->bitmap); + if (idx == 0) + panic("idr_get_new: Invalid leaf state (%p, %p)\n", + idr, il); + idx--; + id |= idx << (layer * IDR_BITS); + if (layer == 0) + break; + if (il->ary[idx] == NULL) { + il = il->ary[idx] = idr_get(idr); + if (il == NULL) + goto out; + } + } + /* + * Allocate the leaf to the consumer. + */ + il->bitmap &= ~(1 << idx); + il->ary[idx] = ptr; + *idp = id; + /* + * Clear bitmaps potentially up to the root. + */ + while (il->bitmap == 0 && ++layer < idr->layers) { + il = stack[layer]; + il->bitmap &= ~(1 << idr_pos(id, layer)); + } + error = 0; +out: + mtx_unlock(&idr->lock); + return (error); +} + +int +idr_get_new_above(struct idr *idr, void *ptr, int starting_id, int *idp) +{ + struct idr_layer *stack[MAX_LEVEL]; + struct idr_layer *il; + int error; + int layer; + int idx, sidx; + int id; + + error = -EAGAIN; + mtx_lock(&idr->lock); + /* + * Compute the layers required to support starting_id and the mask + * at the top layer. + */ +restart: + idx = starting_id; + layer = 0; + while (idx & ~IDR_MASK) { + layer++; + idx >>= IDR_BITS; + } + /* + * Expand the tree until there is free space at or beyond starting_id. + */ + while (idr->layers <= layer || + idr->top->bitmap < (1 << idr_pos(starting_id, idr->layers - 1))) { + if (idr->layers == MAX_LEVEL + 1) { + error = -ENOSPC; + goto out; + } + il = idr_get(idr); + if (il == NULL) + goto out; + il->ary[0] = idr->top; + if (idr->top && idr->top->bitmap == 0) + il->bitmap &= ~1; + idr->top = il; + idr->layers++; + } + il = idr->top; + id = 0; + /* + * Walk the tree following free bitmaps, record our path. + */ + for (layer = idr->layers - 1;; layer--) { + stack[layer] = il; + sidx = idr_pos(starting_id, layer); + /* Returns index numbered from 0 or size if none exists. */ + idx = find_next_bit(&il->bitmap, IDR_SIZE, sidx); + if (idx == IDR_SIZE && sidx == 0) + panic("idr_get_new: Invalid leaf state (%p, %p)\n", + idr, il); + /* + * We may have walked a path where there was a free bit but + * it was lower than what we wanted. Restart the search with + * a larger starting id. id contains the progress we made so + * far. Search the leaf one above this level. This may + * restart as many as MAX_LEVEL times but that is expected + * to be rare. + */ + if (idx == IDR_SIZE) { + starting_id = id + (1 << (layer+1 * IDR_BITS)); + goto restart; + } + if (idx > sidx) + starting_id = 0; /* Search the whole subtree. */ + id |= idx << (layer * IDR_BITS); + if (layer == 0) + break; + if (il->ary[idx] == NULL) { + il = il->ary[idx] = idr_get(idr); + if (il == NULL) + goto out; + } + } + /* + * Allocate the leaf to the consumer. + */ + il->bitmap &= ~(1 << idx); + il->ary[idx] = ptr; + *idp = id; + /* + * Clear bitmaps potentially up to the root. + */ + while (il->bitmap == 0 && ++layer < idr->layers) { + il = stack[layer]; + il->bitmap &= ~(1 << idr_pos(id, layer)); + } + error = 0; +out: + mtx_unlock(&idr->lock); + return (error); +} Modified: projects/ofed/head/sys/ofed/include/linux/list.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/list.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/list.h Sun Jun 13 07:30:51 2010 (r209121) @@ -43,6 +43,11 @@ #include #include +#include +#include +#include +#include + #define prefetch(x) struct list_head { Modified: projects/ofed/head/sys/ofed/include/linux/lockdep.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/lockdep.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/lockdep.h Sun Jun 13 07:30:51 2010 (r209121) @@ -29,7 +29,9 @@ #ifndef _LINUX_LOCKDEP_H_ #define _LINUX_LOCKDEP_H_ -struct lock_class_key; +struct lock_class_key { +}; + #define lockdep_set_class(lock, key) #endif /* _LINUX_LOCKDEP_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/miscdevice.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/miscdevice.h Sun Jun 13 05:24:27 2010 (r209120) +++ projects/ofed/head/sys/ofed/include/linux/miscdevice.h Sun Jun 13 07:30:51 2010 (r209121) @@ -38,8 +38,17 @@ struct miscdevice { int minor; }; -int misc_register(struct miscdevice *misc); -int misc_deregister(struct miscdevice *misc); +static inline int +misc_register(struct miscdevice *misc) +{ + return (0); +} + +static inline int +misc_deregister(struct miscdevice *misc) +{ + return (0); +} #endif /* _LINUX_MISCDEVICE_H_ */ Added: projects/ofed/head/sys/ofed/include/linux/net.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/ofed/head/sys/ofed/include/linux/net.h Sun Jun 13 07:30:51 2010 (r209121) @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***