svn commit: r216785 - in projects/ofed/head/sys/ofed: drivers/infiniband/core drivers/infiniband/hw/mlx4 include/linux

Jeff Roberson jeff at FreeBSD.org
Wed Dec 29 02:24:43 UTC 2010


Author: jeff
Date: Wed Dec 29 02:24:43 2010
New Revision: 216785
URL: http://svn.freebsd.org/changeset/base/216785

Log:
   - Eliminate file descriptor ifdefs related to get_unused_fd() and
     alloc_file() by providing compatible wrappers for these functions.
   - Add support for SIGIO based async file IO and the fasync()
     file operation entry.
   - Document a few cases that are missing compatibility shims and still
     require work.
   - Also document those ifdefs which do not require compatibility shims for
     various reasons.
  
  Sponsored by:	Isilon Systems, iX Systems, and Panasas.

Modified:
  projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
  projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c
  projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c
  projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c
  projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c
  projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c
  projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
  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/linux_compat.c

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/addr.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -585,6 +585,7 @@ void rdma_addr_cancel(struct rdma_dev_ad
 EXPORT_SYMBOL(rdma_addr_cancel);
 
 #ifdef __linux__
+/* XXX Need this callback to reduce timeout time. */
 static int netevent_callback(struct notifier_block *self, unsigned long event,
 	void *ctx)
 {

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/cma.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -1682,6 +1682,7 @@ out:
 }
 
 #ifdef __linux__
+/* XXX I need to add an EVENTHANDLER based system for handling these events. */
 static void cma_ndev_work_handler(struct work_struct *_work)
 {
 	struct cma_ndev_work *work = container_of(_work, struct cma_ndev_work, work);

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/sysfs.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -444,6 +444,7 @@ static void ib_device_release(struct dev
 }
 
 #ifdef __linux__
+/* BSD supports this through devfs(5) and devd(8). */
 static int ib_device_uevent(struct device *device,
 			    struct kobj_uevent_env *env)
 {

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/ucma.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -596,6 +596,7 @@ static void ucma_copy_iboe_route(struct 
 	switch (route->num_paths) {
 	case 0:
 		dev_addr = &route->addr.dev_addr;
+		/* XXX Vlan missing. */
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 		dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
 		if (dev) {

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/umem.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -120,6 +120,7 @@ static void __ib_umem_release(struct ib_
 				      chunk->nents, DMA_BIDIRECTIONAL, &chunk->attrs);
 		for (i = 0; i < chunk->nents; ++i) {
 #ifdef __linux__
+			/* XXX I need to set the proper page flags here too. */
 			struct page *page = sg_page(&chunk->page_list[i]);
 			if (umem->writable && dirty)
 				set_page_dirty_lock(page);

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/core/uverbs_main.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -121,6 +121,7 @@ static ssize_t (*uverbs_cmd_table[])(str
 };
 
 #ifdef __linux__
+/* BSD Does not require a fake mountpoint for all files. */
 static struct vfsmount *uverbs_event_mnt;
 #endif
 
@@ -372,14 +373,12 @@ static unsigned int ib_uverbs_event_poll
 	return pollflags;
 }
 
-#ifdef __linux__
 static int ib_uverbs_event_fasync(int fd, struct file *filp, int on)
 {
 	struct ib_uverbs_event_file *file = filp->private_data;
 
 	return fasync_helper(fd, filp, on, &file->async_queue);
 }
-#endif
 
 static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
 {
@@ -409,9 +408,7 @@ static const struct file_operations uver
 	.read 	 = ib_uverbs_event_read,
 	.poll    = ib_uverbs_event_poll,
 	.release = ib_uverbs_event_close,
-#ifdef __linux__
 	.fasync  = ib_uverbs_event_fasync
-#endif
 };
 
 void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
@@ -448,10 +445,7 @@ void ib_uverbs_comp_handler(struct ib_cq
 	wake_up_interruptible(&file->poll_wait);
 	if (file->filp)
 		selwakeup(&file->filp->f_selinfo);
-#ifdef __linux__
-	/* funsetown ? */
 	kill_fasync(&file->async_queue, SIGIO, POLL_IN);
-#endif
 }
 
 static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
@@ -486,10 +480,7 @@ static void ib_uverbs_async_handler(stru
 	wake_up_interruptible(&file->async_file->poll_wait);
 	if (file->async_file->filp)
 		selwakeup(&file->async_file->filp->f_selinfo);
-#ifdef __linux__	
-	/* funsetown? */
 	kill_fasync(&file->async_file->async_queue, SIGIO, POLL_IN);
-#endif
 }
 
 void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
@@ -563,7 +554,6 @@ struct file *ib_uverbs_alloc_event_file(
 	ev_file->is_async    = is_async;
 	ev_file->is_closed   = 0;
 
-#ifdef __linux__
 	*fd = get_unused_fd();
 	if (*fd < 0) {
 		ret = *fd;
@@ -582,28 +572,12 @@ struct file *ib_uverbs_alloc_event_file(
 		goto err_fd;
 	}
 
-#else
-	filp = kzalloc(sizeof(*filp), GFP_KERNEL);
-	if (filp == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
-	filp->f_op = &uverbs_event_fops;
-	ret = falloc(curthread, &filp->_file, fd);
-	if (ret) {
-		ret = -ret;
-		goto err;
-	}
-	finit(filp->_file, FREAD, DTYPE_DEV, filp, &badfileops);
-#endif
 	filp->private_data = ev_file;
 
 	return filp;
 
-#ifdef __linux__
 err_fd:
 	put_unused_fd(*fd);
-#endif
 
 err:
 	kfree(ev_file);

Modified: projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c
==============================================================================
--- projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/drivers/infiniband/hw/mlx4/main.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -1135,6 +1135,7 @@ static int update_ipv6_gids(struct mlx4_
 		goto out;
 	}
 
+	/* XXX vlan */
 	read_lock(&dev_base_lock);
 	for_each_netdev(&init_net, tmp) {
 		if (ndev && (tmp == ndev
@@ -1195,7 +1196,6 @@ static int update_ipv6_gids(struct mlx4_
 out:
 	kfree(work);
 	return ret;
-	return 0;
 }
 
 static void handle_en_event(struct mlx4_ib_dev *dev, int port, unsigned long event)
@@ -1221,6 +1221,7 @@ static void netdev_removed(struct mlx4_i
 	update_ipv6_gids(dev, port, 1);
 }
 
+/* XXX netdev event needed. */
 static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event,
 				void *ptr)
 {

Modified: projects/ofed/head/sys/ofed/include/linux/file.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/file.h	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/include/linux/file.h	Wed Dec 29 02:24:43 2010	(r216785)
@@ -54,6 +54,10 @@ linux_fget(unsigned int fd)
 static inline void
 fput(struct linux_file *filp)
 {
+	if (filp->_file == NULL) {
+		kfree(filp);
+		return;
+	}
 	if (refcount_release(&filp->_file->f_count)) {
 		_fdrop(filp->_file, curthread);
 		kfree(filp);
@@ -63,21 +67,53 @@ fput(struct linux_file *filp)
 static inline void
 put_unused_fd(unsigned int fd)
 {
-	struct linux_file *file;
+	struct file *file;
 
-	file = linux_fget(fd);
+	file = fget_unlocked(curthread->td_proc->p_fd, fd);
 	if (file == NULL)
 		return;
-	if (file->_file)
-		fdclose(curthread->td_proc->p_fd, file->_file, fd, curthread);
+	fdclose(curthread->td_proc->p_fd, file, fd, curthread);
 }
 
 static inline void
 fd_install(unsigned int fd, struct linux_file *filp)
 {
-	filp->_file->f_ops = &linuxfileops;
+	struct file *file;
+
+	file = fget_unlocked(curthread->td_proc->p_fd, fd);
+	filp->_file = file;
+        finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
+}
+
+static inline int
+get_unused_fd(void)
+{
+	struct file *file;
+	int error;
+	int fd;
+
+	error = falloc(curthread, &file, &fd);
+	if (error)
+		return -error;
+	return fd;
 }
 
+static inline struct linux_file *
+_alloc_file(int mode, const struct file_operations *fops)
+{
+	struct linux_file *filp;
+
+	filp = kzalloc(sizeof(*filp), GFP_KERNEL);
+	if (filp == NULL) 
+		return (NULL);
+	filp->f_op = fops;
+	filp->f_mode = mode;
+
+	return filp;
+}
+
+#define	alloc_file(mnt, root, mode, fops)	_alloc_file((mode), (fops))
+
 #define	file	linux_file
 #define	fget	linux_fget
 

Modified: projects/ofed/head/sys/ofed/include/linux/fs.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/fs.h	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/include/linux/fs.h	Wed Dec 29 02:24:43 2010	(r216785)
@@ -68,12 +68,30 @@ struct linux_file {
 	const struct file_operations	*f_op;
 	void 		*private_data;
 	int		f_flags;
+	int		f_mode;	/* Just starting mode. */
 	struct dentry	*f_dentry;
 	struct dentry	f_dentry_store;
 	struct selinfo	f_selinfo;
+	struct sigio	*f_sigio;
 };
 
-#define	file	linux_file
+#define	file		linux_file
+#define	fasync_struct	sigio *
+
+#define	fasync_helper(fd, filp, on, queue)				\
+({									\
+	if ((on))							\
+		*(queue) = &(filp)->f_sigio;				\
+	else								\
+		*(queue) = NULL;					\
+	0;								\
+})
+
+#define	kill_fasync(queue, sig, pollstat)				\
+do {									\
+	if (*(queue) != NULL)						\
+		pgsigio(*(queue), (sig), 0);				\
+} while (0)
 
 typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
 
@@ -86,6 +104,7 @@ struct file_operations {
 	int (*mmap)(struct file *, struct vm_area_struct *);
 	int (*open)(struct inode *, struct file *);
 	int (*release)(struct inode *, struct file *);
+	int (*fasync)(int, struct file *, int);
 #if 0
 	/* We do not support these methods.  Don't permit them to compile. */
 	loff_t (*llseek)(struct file *, loff_t, int);
@@ -100,7 +119,6 @@ struct file_operations {
 	int (*flush)(struct file *, fl_owner_t id);
 	int (*fsync)(struct file *, struct dentry *, int datasync);
 	int (*aio_fsync)(struct kiocb *, int datasync);
-	int (*fasync)(int, struct file *, int);
 	int (*lock)(struct file *, int, struct file_lock *);
 	ssize_t (*sendpage)(struct file *, struct page *, int, size_t,
 	    loff_t *, int);
@@ -115,6 +133,11 @@ struct file_operations {
 	int (*setlease)(struct file *, long, struct file_lock **);
 #endif
 };
+#define	fops_get(fops)	(fops)
+
+#define	FMODE_READ	FREAD
+#define	FMODE_WRITE	FWRITE
+#define	FMODE_EXEC	FEXEC
 
 static inline int
 register_chrdev_region(dev_t dev, unsigned range, const char *name)

Modified: projects/ofed/head/sys/ofed/include/linux/linux_compat.c
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/linux_compat.c	Tue Dec 28 23:50:13 2010	(r216784)
+++ projects/ofed/head/sys/ofed/include/linux/linux_compat.c	Wed Dec 29 02:24:43 2010	(r216785)
@@ -34,6 +34,9 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/bus.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filio.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -440,8 +443,6 @@ linux_dev_mmap_single(struct cdev *dev, 
 	return (error);
 }
 
-
-
 struct cdevsw linuxcdevsw = {
 	.d_version = D_VERSION,
 	.d_flags = D_TRACKCLOSE,
@@ -510,15 +511,52 @@ linux_file_close(struct file *file, stru
 	filp = (struct linux_file *)file->f_data;
 	filp->f_flags = file->f_flag;
 	error = -filp->f_op->release(NULL, filp);
+	funsetown(&filp->f_sigio);
 	kfree(filp);
 
 	return (error);
 }
 
+static int
+linux_file_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *cred,
+    struct thread *td)
+{
+	struct linux_file *filp;
+	int error;
+
+	filp = (struct linux_file *)fp->f_data;
+	filp->f_flags = fp->f_flag;
+	error = 0;
+
+	switch (cmd) {
+	case FIONBIO:
+		break;
+	case FIOASYNC:
+		if (filp->f_op->fasync == NULL)
+			break;
+		error = filp->f_op->fasync(0, filp, fp->f_flag & FASYNC);
+		break;
+	case FIOSETOWN:
+		error = fsetown(*(int *)data, &filp->f_sigio);
+		if (error == 0)
+			error = filp->f_op->fasync(0, filp,
+			    fp->f_flag & FASYNC);
+		break;
+	case FIOGETOWN:
+		*(int *)data = fgetown(&filp->f_sigio);
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+	return (error);
+}
+
 struct fileops linuxfileops = {
 	.fo_read = linux_file_read,
 	.fo_poll = linux_file_poll,
-	.fo_close = linux_file_close
+	.fo_close = linux_file_close,
+	.fo_ioctl = linux_file_ioctl
 };
 
 /*


More information about the svn-src-projects mailing list