Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1e4594b authored by Al Viro's avatar Al Viro
Browse files

switch infiniband uverbs to anon_inodes



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2f99cc6e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ config INFINIBAND_USER_MAD

config INFINIBAND_USER_ACCESS
	tristate "InfiniBand userspace access (verbs and CM)"
	select ANON_INODES
	---help---
	  Userspace InfiniBand access support.  This enables the
	  kernel side of userspace verbs and the userspace
+1 −1
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ extern struct idr ib_uverbs_srq_idr;
void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj);

struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
					int is_async, int *fd);
					int is_async);
struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd);

void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
+20 −5
Original line number Diff line number Diff line
@@ -301,10 +301,15 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,

	resp.num_comp_vectors = file->device->num_comp_vectors;

	filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd);
	ret = get_unused_fd();
	if (ret < 0)
		goto err_free;
	resp.async_fd = ret;

	filp = ib_uverbs_alloc_event_file(file, 1);
	if (IS_ERR(filp)) {
		ret = PTR_ERR(filp);
		goto err_free;
		goto err_fd;
	}

	if (copy_to_user((void __user *) (unsigned long) cmd.response,
@@ -332,9 +337,11 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
	return in_len;

err_file:
	put_unused_fd(resp.async_fd);
	fput(filp);

err_fd:
	put_unused_fd(resp.async_fd);

err_free:
	ibdev->dealloc_ucontext(ucontext);

@@ -715,6 +722,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
	struct ib_uverbs_create_comp_channel	   cmd;
	struct ib_uverbs_create_comp_channel_resp  resp;
	struct file				  *filp;
	int ret;

	if (out_len < sizeof resp)
		return -ENOSPC;
@@ -722,9 +730,16 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
	if (copy_from_user(&cmd, buf, sizeof cmd))
		return -EFAULT;

	filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd);
	if (IS_ERR(filp))
	ret = get_unused_fd();
	if (ret < 0)
		return ret;
	resp.fd = ret;

	filp = ib_uverbs_alloc_event_file(file, 0);
	if (IS_ERR(filp)) {
		put_unused_fd(resp.fd);
		return PTR_ERR(filp);
	}

	if (copy_to_user((void __user *) (unsigned long) cmd.response,
			 &resp, sizeof resp)) {
+7 −75
Original line number Diff line number Diff line
@@ -41,8 +41,8 @@
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/anon_inodes.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/cdev.h>

#include <asm/uaccess.h>
@@ -53,8 +53,6 @@ MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("InfiniBand userspace verbs access");
MODULE_LICENSE("Dual BSD/GPL");

#define INFINIBANDEVENTFS_MAGIC	0x49426576	/* "IBev" */

enum {
	IB_UVERBS_MAJOR       = 231,
	IB_UVERBS_BASE_MINOR  = 192,
@@ -111,8 +109,6 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
	[IB_USER_VERBS_CMD_DESTROY_SRQ]   	= ib_uverbs_destroy_srq,
};

static struct vfsmount *uverbs_event_mnt;

static void ib_uverbs_add_one(struct ib_device *device);
static void ib_uverbs_remove_one(struct ib_device *device);

@@ -489,12 +485,10 @@ void ib_uverbs_event_handler(struct ib_event_handler *handler,
}

struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
					int is_async, int *fd)
					int is_async)
{
	struct ib_uverbs_event_file *ev_file;
	struct path path;
	struct file *filp;
	int ret;

	ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL);
	if (!ev_file)
@@ -509,38 +503,12 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
	ev_file->is_async    = is_async;
	ev_file->is_closed   = 0;

	*fd = get_unused_fd();
	if (*fd < 0) {
		ret = *fd;
		goto err;
	}

	/*
	 * fops_get() can't fail here, because we're coming from a
	 * system call on a uverbs file, which will already have a
	 * module reference.
	 */
	path.mnt = uverbs_event_mnt;
	path.dentry = uverbs_event_mnt->mnt_root;
	path_get(&path);
	filp = alloc_file(&path, FMODE_READ, fops_get(&uverbs_event_fops));
	if (!filp) {
		ret = -ENFILE;
		goto err_fd;
	}

	filp->private_data = ev_file;
	filp = anon_inode_getfile("[infinibandevent]", &uverbs_event_fops,
				  ev_file, O_RDONLY);
	if (IS_ERR(filp))
		kfree(ev_file);

	return filp;

err_fd:
	fops_put(&uverbs_event_fops);
	path_put(&path);
	put_unused_fd(*fd);

err:
	kfree(ev_file);
	return ERR_PTR(ret);
}

/*
@@ -825,21 +793,6 @@ static void ib_uverbs_remove_one(struct ib_device *device)
	kfree(uverbs_dev);
}

static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
			       const char *dev_name, void *data,
			       struct vfsmount *mnt)
{
	return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
			     INFINIBANDEVENTFS_MAGIC, mnt);
}

static struct file_system_type uverbs_event_fs = {
	/* No owner field so module can be unloaded */
	.name    = "infinibandeventfs",
	.get_sb  = uverbs_event_get_sb,
	.kill_sb = kill_litter_super
};

static int __init ib_uverbs_init(void)
{
	int ret;
@@ -864,33 +817,14 @@ static int __init ib_uverbs_init(void)
		goto out_class;
	}

	ret = register_filesystem(&uverbs_event_fs);
	if (ret) {
		printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n");
		goto out_class;
	}

	uverbs_event_mnt = kern_mount(&uverbs_event_fs);
	if (IS_ERR(uverbs_event_mnt)) {
		ret = PTR_ERR(uverbs_event_mnt);
		printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n");
		goto out_fs;
	}

	ret = ib_register_client(&uverbs_client);
	if (ret) {
		printk(KERN_ERR "user_verbs: couldn't register client\n");
		goto out_mnt;
		goto out_class;
	}

	return 0;

out_mnt:
	mntput(uverbs_event_mnt);

out_fs:
	unregister_filesystem(&uverbs_event_fs);

out_class:
	class_destroy(uverbs_class);

@@ -904,8 +838,6 @@ static int __init ib_uverbs_init(void)
static void __exit ib_uverbs_cleanup(void)
{
	ib_unregister_client(&uverbs_client);
	mntput(uverbs_event_mnt);
	unregister_filesystem(&uverbs_event_fs);
	class_destroy(uverbs_class);
	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
	idr_destroy(&ib_uverbs_pd_idr);