⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uverbs_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
						  struct ib_ucq_object, uobject);	ib_uverbs_async_handler(uobj->uverbs_file, uobj->uobject.user_handle,				event->event, &uobj->async_list,				&uobj->async_events_reported);				}void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr){	struct ib_uevent_object *uobj;	uobj = container_of(event->element.qp->uobject,			    struct ib_uevent_object, uobject);	ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,				event->event, &uobj->event_list,				&uobj->events_reported);}void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr){	struct ib_uevent_object *uobj;	uobj = container_of(event->element.srq->uobject,			    struct ib_uevent_object, uobject);	ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,				event->event, &uobj->event_list,				&uobj->events_reported);}void ib_uverbs_event_handler(struct ib_event_handler *handler,			     struct ib_event *event){	struct ib_uverbs_file *file =		container_of(handler, struct ib_uverbs_file, event_handler);	ib_uverbs_async_handler(file, event->element.port_num, event->event,				NULL, NULL);}struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,					int is_async, int *fd){	struct ib_uverbs_event_file *ev_file;	struct file *filp;	int ret;	ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL);	if (!ev_file)		return ERR_PTR(-ENOMEM);	kref_init(&ev_file->ref);	spin_lock_init(&ev_file->lock);	INIT_LIST_HEAD(&ev_file->event_list);	init_waitqueue_head(&ev_file->poll_wait);	ev_file->uverbs_file = uverbs_file;	ev_file->async_queue = NULL;	ev_file->is_async    = is_async;	*fd = get_unused_fd();	if (*fd < 0) {		ret = *fd;		goto err;	}	filp = get_empty_filp();	if (!filp) {		ret = -ENFILE;		goto err_fd;	}	ev_file->file      = filp;	/*	 * 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.	 */	filp->f_op 	   = fops_get(&uverbs_event_fops);	filp->f_vfsmnt 	   = mntget(uverbs_event_mnt);	filp->f_dentry 	   = dget(uverbs_event_mnt->mnt_root);	filp->f_mapping    = filp->f_dentry->d_inode->i_mapping;	filp->f_flags      = O_RDONLY;	filp->f_mode       = FMODE_READ;	filp->private_data = ev_file;	return filp;err_fd:	put_unused_fd(*fd);err:	kfree(ev_file);	return ERR_PTR(ret);}/* * Look up a completion event file by FD.  If lookup is successful, * takes a ref to the event file struct that it returns; if * unsuccessful, returns NULL. */struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd){	struct ib_uverbs_event_file *ev_file = NULL;	struct file *filp;	filp = fget(fd);	if (!filp)		return NULL;	if (filp->f_op != &uverbs_event_fops)		goto out;	ev_file = filp->private_data;	if (ev_file->is_async) {		ev_file = NULL;		goto out;	}	kref_get(&ev_file->ref);out:	fput(filp);	return ev_file;}static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,			     size_t count, loff_t *pos){	struct ib_uverbs_file *file = filp->private_data;	struct ib_uverbs_cmd_hdr hdr;	if (count < sizeof hdr)		return -EINVAL;	if (copy_from_user(&hdr, buf, sizeof hdr))		return -EFAULT;	if (hdr.in_words * 4 != count)		return -EINVAL;	if (hdr.command < 0				||	    hdr.command >= ARRAY_SIZE(uverbs_cmd_table) ||	    !uverbs_cmd_table[hdr.command]		||	    !(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command)))		return -EINVAL;	if (!file->ucontext &&	    hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT)		return -EINVAL;	return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr,					     hdr.in_words * 4, hdr.out_words * 4);}static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma){	struct ib_uverbs_file *file = filp->private_data;	if (!file->ucontext)		return -ENODEV;	else		return file->device->ib_dev->mmap(file->ucontext, vma);}static int ib_uverbs_open(struct inode *inode, struct file *filp){	struct ib_uverbs_device *dev;	struct ib_uverbs_file *file;	int ret;	spin_lock(&map_lock);	dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR];	if (dev)		kref_get(&dev->ref);	spin_unlock(&map_lock);	if (!dev)		return -ENXIO;	if (!try_module_get(dev->ib_dev->owner)) {		ret = -ENODEV;		goto err;	}	file = kmalloc(sizeof *file, GFP_KERNEL);	if (!file) {		ret = -ENOMEM;		goto err_module;	}	file->device	 = dev;	file->ucontext	 = NULL;	file->async_file = NULL;	kref_init(&file->ref);	init_MUTEX(&file->mutex);	filp->private_data = file;	return 0;err_module:	module_put(dev->ib_dev->owner);err:	kref_put(&dev->ref, ib_uverbs_release_dev);	return ret;}static int ib_uverbs_close(struct inode *inode, struct file *filp){	struct ib_uverbs_file *file = filp->private_data;	ib_uverbs_cleanup_ucontext(file, file->ucontext);	if (file->async_file)		kref_put(&file->async_file->ref, ib_uverbs_release_event_file);	kref_put(&file->ref, ib_uverbs_release_file);	return 0;}static struct file_operations uverbs_fops = {	.owner 	 = THIS_MODULE,	.write 	 = ib_uverbs_write,	.open 	 = ib_uverbs_open,	.release = ib_uverbs_close};static struct file_operations uverbs_mmap_fops = {	.owner 	 = THIS_MODULE,	.write 	 = ib_uverbs_write,	.mmap    = ib_uverbs_mmap,	.open 	 = ib_uverbs_open,	.release = ib_uverbs_close};static struct ib_client uverbs_client = {	.name   = "uverbs",	.add    = ib_uverbs_add_one,	.remove = ib_uverbs_remove_one};static ssize_t show_ibdev(struct class_device *class_dev, char *buf){	struct ib_uverbs_device *dev = class_get_devdata(class_dev);	if (!dev)		return -ENODEV;	return sprintf(buf, "%s\n", dev->ib_dev->name);}static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf){	struct ib_uverbs_device *dev = class_get_devdata(class_dev);	if (!dev)		return -ENODEV;	return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver);}static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);static ssize_t show_abi_version(struct class *class, char *buf){	return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION);}static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);static void ib_uverbs_add_one(struct ib_device *device){	struct ib_uverbs_device *uverbs_dev;	if (!device->alloc_ucontext)		return;	uverbs_dev = kzalloc(sizeof *uverbs_dev, GFP_KERNEL);	if (!uverbs_dev)		return;	kref_init(&uverbs_dev->ref);	spin_lock(&map_lock);	uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);	if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) {		spin_unlock(&map_lock);		goto err;	}	set_bit(uverbs_dev->devnum, dev_map);	spin_unlock(&map_lock);	uverbs_dev->ib_dev           = device;	uverbs_dev->num_comp_vectors = 1;	uverbs_dev->dev = cdev_alloc();	if (!uverbs_dev->dev)		goto err;	uverbs_dev->dev->owner = THIS_MODULE;	uverbs_dev->dev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;	kobject_set_name(&uverbs_dev->dev->kobj, "uverbs%d", uverbs_dev->devnum);	if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))		goto err_cdev;	uverbs_dev->class_dev = class_device_create(uverbs_class, NULL,						    uverbs_dev->dev->dev,						    device->dma_device,						    "uverbs%d", uverbs_dev->devnum);	if (IS_ERR(uverbs_dev->class_dev))		goto err_cdev;	class_set_devdata(uverbs_dev->class_dev, uverbs_dev);	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_ibdev))		goto err_class;	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_abi_version))		goto err_class;	spin_lock(&map_lock);	dev_table[uverbs_dev->devnum] = uverbs_dev;	spin_unlock(&map_lock);	ib_set_client_data(device, &uverbs_client, uverbs_dev);	return;err_class:	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);err_cdev:	cdev_del(uverbs_dev->dev);	clear_bit(uverbs_dev->devnum, dev_map);err:	kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);	return;}static void ib_uverbs_remove_one(struct ib_device *device){	struct ib_uverbs_device *uverbs_dev = ib_get_client_data(device, &uverbs_client);	if (!uverbs_dev)		return;	class_set_devdata(uverbs_dev->class_dev, NULL);	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);	cdev_del(uverbs_dev->dev);	spin_lock(&map_lock);	dev_table[uverbs_dev->devnum] = NULL;	spin_unlock(&map_lock);	clear_bit(uverbs_dev->devnum, dev_map);	kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);}static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,					       const char *dev_name, void *data){	return get_sb_pseudo(fs_type, "infinibandevent:", NULL,			     INFINIBANDEVENTFS_MAGIC);}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;	spin_lock_init(&map_lock);	ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES,				     "infiniband_verbs");	if (ret) {		printk(KERN_ERR "user_verbs: couldn't register device number\n");		goto out;	}	uverbs_class = class_create(THIS_MODULE, "infiniband_verbs");	if (IS_ERR(uverbs_class)) {		ret = PTR_ERR(uverbs_class);		printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n");		goto out_chrdev;	}	ret = class_create_file(uverbs_class, &class_attr_abi_version);	if (ret) {		printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");		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;	}	return 0;out_mnt:	mntput(uverbs_event_mnt);out_fs:	unregister_filesystem(&uverbs_event_fs);out_class:	class_destroy(uverbs_class);out_chrdev:	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);out:	return ret;}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);	idr_destroy(&ib_uverbs_mr_idr);	idr_destroy(&ib_uverbs_mw_idr);	idr_destroy(&ib_uverbs_ah_idr);	idr_destroy(&ib_uverbs_cq_idr);	idr_destroy(&ib_uverbs_qp_idr);	idr_destroy(&ib_uverbs_srq_idr);}module_init(ib_uverbs_init);module_exit(ib_uverbs_cleanup);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -