From owner-svn-src-projects@FreeBSD.ORG Wed Dec 29 02:24:43 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 D85F5106564A; Wed, 29 Dec 2010 02:24:43 +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 C5DD58FC08; Wed, 29 Dec 2010 02:24:43 +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 oBT2OhJm084174; Wed, 29 Dec 2010 02:24:43 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oBT2Oh3s084163; Wed, 29 Dec 2010 02:24:43 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201012290224.oBT2Oh3s084163@svn.freebsd.org> From: Jeff Roberson Date: Wed, 29 Dec 2010 02:24:43 +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: r216785 - in projects/ofed/head/sys/ofed: drivers/infiniband/core drivers/infiniband/hw/mlx4 include/linux 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: Wed, 29 Dec 2010 02:24:43 -0000 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 #include #include +#include +#include +#include #include #include @@ -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 }; /*