From: Evgeniy Polyakov Remove mmap interface until it's design will be good for everyone. Signed-off-by: Evgeniy Polyakov Signed-off-by: Andrew Morton --- kernel/kevent/kevent.c | 1 kernel/kevent/kevent_user.c | 196 ---------------------------------- 2 files changed, 1 insertion(+), 196 deletions(-) diff -puN kernel/kevent/kevent.c~kevent-remove-mmap-interface kernel/kevent/kevent.c --- a/kernel/kevent/kevent.c~kevent-remove-mmap-interface +++ a/kernel/kevent/kevent.c @@ -165,7 +165,6 @@ static void __kevent_requeue(struct keve spin_lock_irqsave(&k->user->ready_lock, flags); if (!(k->flags & KEVENT_READY)) { - kevent_user_ring_add_event(k); list_add_tail(&k->ready_entry, &k->user->ready_list); k->flags |= KEVENT_READY; k->user->ready_num++; diff -puN kernel/kevent/kevent_user.c~kevent-remove-mmap-interface kernel/kevent/kevent_user.c --- a/kernel/kevent/kevent_user.c~kevent-remove-mmap-interface +++ a/kernel/kevent/kevent_user.c @@ -53,90 +53,6 @@ static unsigned int kevent_user_poll(str return mask; } -static inline void kevent_user_ring_set(struct kevent_user *u, unsigned int num) -{ - u->pring[0]->index = num; -} - -static int kevent_user_ring_grow(struct kevent_user *u) -{ - unsigned int idx; - - idx = (u->kevent_num + u->pring[0]->index + 1) / KEVENTS_ON_PAGE; - if (idx >= u->pages_in_use) { - u->pring[idx] = (void *)__get_free_page(GFP_KERNEL); - if (!u->pring[idx]) - return -ENOMEM; - u->pages_in_use++; - } - return 0; -} - -/* - * Called under kevent_user->ready_lock, so updates are always protected. - */ -void kevent_user_ring_add_event(struct kevent *k) -{ - unsigned int pidx, off; - struct kevent_mring *ring, *copy_ring; - - ring = k->user->pring[0]; - - pidx = ring->index/KEVENTS_ON_PAGE; - off = ring->index%KEVENTS_ON_PAGE; - - if (unlikely(pidx >= k->user->pages_in_use)) { - printk("%s: ring->index: %u, on_page: %lu, pidx: %u, pages_in_use: %u.\n", - __func__, ring->index, KEVENTS_ON_PAGE, pidx, k->user->pages_in_use); - return; - } - - copy_ring = k->user->pring[pidx]; - - copy_ring->event[off].id.raw[0] = k->event.id.raw[0]; - copy_ring->event[off].id.raw[1] = k->event.id.raw[1]; - copy_ring->event[off].ret_flags = k->event.ret_flags; - - if (++ring->index >= KEVENT_MAX_EVENTS) - ring->index = 0; -} - -/* - * Initialize mmap ring buffer. - * It will store ready kevents, so userspace could get them directly instead - * of using syscall. Esentially syscall becomes just a waiting point. - */ -static int kevent_user_ring_init(struct kevent_user *u) -{ - u->pring = kzalloc(KEVENT_MAX_PAGES * sizeof(struct kevent_mring *), GFP_KERNEL); - if (!u->pring) - return -ENOMEM; - - u->pring[0] = (struct kevent_mring *)__get_free_page(GFP_KERNEL); - if (!u->pring[0]) - goto err_out_free; - - u->pages_in_use = 1; - kevent_user_ring_set(u, 0); - - return 0; - -err_out_free: - kfree(u->pring); - - return -ENOMEM; -} - -static void kevent_user_ring_fini(struct kevent_user *u) -{ - int i; - - for (i = 0; i < u->pages_in_use; ++i) - free_page((unsigned long)u->pring[i]); - - kfree(u->pring); -} - static int kevent_user_open(struct inode *inode, struct file *file) { struct kevent_user *u; @@ -156,11 +72,6 @@ static int kevent_user_open(struct inode atomic_set(&u->refcnt, 1); - if (unlikely(kevent_user_ring_init(u))) { - kfree(u); - return -ENOMEM; - } - file->private_data = u; return 0; } @@ -180,55 +91,10 @@ static inline void kevent_user_put(struc { if (atomic_dec_and_test(&u->refcnt)) { kevent_stat_print(u); - kevent_user_ring_fini(u); kfree(u); } } -static struct page *kevent_user_nopage(struct vm_area_struct *vma, unsigned long addr, int *type) -{ - struct kevent_user *u = vma->vm_file->private_data; - unsigned long off = (addr - vma->vm_start)/PAGE_SIZE; - - if (type) - *type = VM_FAULT_MINOR; - - if (off >= u->pages_in_use) - goto err_out_sigbus; - - return virt_to_page(u->pring[off]); - -err_out_sigbus: - return NOPAGE_SIGBUS; -} - -static struct vm_operations_struct kevent_user_vm_ops = { - .nopage = &kevent_user_nopage, -}; - -/* - * Mmap implementation for ring buffer, which is created as array - * of pages, so vm_pgoff is an offset (in pages, not in bytes) of - * the first page to be mapped. - */ -static int kevent_user_mmap(struct file *file, struct vm_area_struct *vma) -{ - unsigned long start = vma->vm_start; - struct kevent_user *u = file->private_data; - - if (vma->vm_flags & VM_WRITE) - return -EPERM; - - vma->vm_ops = &kevent_user_vm_ops; - vma->vm_flags |= VM_RESERVED; - vma->vm_file = file; - - if (vm_insert_page(vma, start, virt_to_page(u->pring[0]))) - return -EFAULT; - - return 0; -} - static inline int kevent_compare_id(struct kevent_id *left, struct kevent_id *right) { return (left->raw_u64 > right->raw_u64)?-1:(right->raw_u64 - left->raw_u64); @@ -602,11 +468,6 @@ int kevent_user_add_ukevent(struct ukeve struct kevent *k; int err; - if (kevent_user_ring_grow(u)) { - err = -ENOMEM; - goto err_out_exit; - } - k = kmem_cache_alloc(kevent_cache, GFP_KERNEL); if (!k) { err = -ENOMEM; @@ -761,7 +622,6 @@ static int kevent_user_wait(struct file } static struct file_operations kevent_user_fops = { - .mmap = kevent_user_mmap, .open = kevent_user_open, .release = kevent_user_release, .poll = kevent_user_poll, @@ -841,61 +701,7 @@ out_fput: */ asmlinkage long sys_kevent_wait(int ctl_fd, unsigned int start, unsigned int num, __u64 timeout) { - int err = -EINVAL; - struct file *file; - struct kevent_user *u; - struct kevent *k; - struct mukevent *muk; - unsigned int idx, off; - unsigned long flags; - - if (start + num >= KEVENT_MAX_EVENTS || - start >= KEVENT_MAX_EVENTS || - num >= KEVENT_MAX_EVENTS) - return -EINVAL; - - file = fget(ctl_fd); - if (!file) - return -ENODEV; - - if (file->f_op != &kevent_user_fops) - goto out_fput; - u = file->private_data; - - if (((start + num) / KEVENTS_ON_PAGE) >= u->pages_in_use || - (start / KEVENTS_ON_PAGE) >= u->pages_in_use) - goto out_fput; - - spin_lock_irqsave(&u->kevent_lock, flags); - while (num > 0) { - idx = start / KEVENTS_ON_PAGE; - off = start % KEVENTS_ON_PAGE; - - muk = &u->pring[idx]->event[off]; - k = __kevent_search(&muk->id, u); - if (unlikely(!k)) { - spin_unlock_irqrestore(&u->kevent_lock, flags); - goto out_fput; - } - - if (++start >= KEVENT_MAX_EVENTS) - start = 0; - num--; - } - spin_unlock_irqrestore(&u->kevent_lock, flags); - - if (!(file->f_flags & O_NONBLOCK)) { - wait_event_interruptible_timeout(u->wait, - u->ready_num >= 1, - clock_t_to_jiffies(nsec_to_clock_t(timeout))); - } - - fput(file); - - return (u->ready_num >= 1)?0:-EAGAIN; -out_fput: - fput(file); - return err; + return -EINVAL; } /* _