Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Jun 2010 07:30:52 +0000 (UTC)
From:      Jeff Roberson <jeff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r209121 - in projects/ofed/head/sys/ofed/include: asm linux net
Message-ID:  <201006130730.o5D7UqYS050291@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <linux/uaccess.h>
 
-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 <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/wait.h>
 
 #include <sys/param.h>
 #include <sys/systm.h>

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 <linux/types.h>
-
-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 <sys/param.h>
 
-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 <sys/conf.h>
 #include <sys/types.h>
 #include <sys/vnode.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
 #include <linux/types.h>
 #include <linux/wait.h>
 
@@ -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 <linux/netdevice.h>
 
+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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/stdarg.h>
+
+#include <linux/kobject.h>
+#include <linux/slab.h>
+
+MALLOC_DEFINE(M_KMALLOC, "linux", "Linux kmalloc compat");
+
+#include <linux/rbtree.h>
+/* 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/stdarg.h>
+
+#include <linux/bitops.h>
+#include <linux/kobject.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/err.h>
+
+/*
+ * 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 <sys/vnode.h>
 #include <sys/conf.h>
 
+#include <sys/socket.h>
+#include <net/if_types.h>
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+
 #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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006130730.o5D7UqYS050291>