On Tue, Apr 18 2017, Jerry Zhang wrote: > There were individual waitqueues for each epfile but eps_enable > would iterate through all of them, resulting in essentially the > same wakeup time. > > The waitqueue represents the function being enabled, so a central > waitqueue in ffs_data makes more sense and is less redundant. > > Also use wake_up_interruptible to reflect use of > wait_event_interruptible. > > Signed-off-by: Jerry Zhang <zhangjerry@xxxxxxxxxx> Acked-by: Michal Nazarewicz <mina86@xxxxxxxxxx> > --- > drivers/usb/gadget/function/f_fs.c | 19 ++++++++++--------- > drivers/usb/gadget/function/u_fs.h | 3 +++ > 2 files changed, 13 insertions(+), 9 deletions(-) > > diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c > index 48de9e013ba8..0abb2e14eb9a 100644 > --- a/drivers/usb/gadget/function/f_fs.c > +++ b/drivers/usb/gadget/function/f_fs.c > @@ -127,7 +127,6 @@ struct ffs_ep { > struct ffs_epfile { > /* Protects ep->ep and ep->req. */ > struct mutex mutex; > - wait_queue_head_t wait; > > struct ffs_data *ffs; > struct ffs_ep *ep; /* P: ffs->eps_lock */ > @@ -890,7 +889,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) > if (file->f_flags & O_NONBLOCK) > return -EAGAIN; > > - ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep)); > + ret = wait_event_interruptible( > + epfile->ffs->wait, (ep = epfile->ep)); > if (ret) > return -EINTR; > } > @@ -1204,7 +1204,8 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, > if (file->f_flags & O_NONBLOCK) > return -EAGAIN; > > - ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep)); > + ret = wait_event_interruptible( > + epfile->ffs->wait, (ep = epfile->ep)); > if (ret) > return -EINTR; > } > @@ -1602,7 +1603,8 @@ static void ffs_data_put(struct ffs_data *ffs) > pr_info("%s(): freeing\n", __func__); > ffs_data_clear(ffs); > BUG_ON(waitqueue_active(&ffs->ev.waitq) || > - waitqueue_active(&ffs->ep0req_completion.wait)); > + waitqueue_active(&ffs->ep0req_completion.wait) || > + waitqueue_active(&ffs->wait)); > kfree(ffs->dev_name); > kfree(ffs); > } > @@ -1649,6 +1651,7 @@ static struct ffs_data *ffs_data_new(void) > mutex_init(&ffs->mutex); > spin_lock_init(&ffs->eps_lock); > init_waitqueue_head(&ffs->ev.waitq); > + init_waitqueue_head(&ffs->wait); > init_completion(&ffs->ep0req_completion); > > /* XXX REVISIT need to update it in some places, or do we? */ > @@ -1770,7 +1773,6 @@ static int ffs_epfiles_create(struct ffs_data *ffs) > for (i = 1; i <= count; ++i, ++epfile) { > epfile->ffs = ffs; > mutex_init(&epfile->mutex); > - init_waitqueue_head(&epfile->wait); > if (ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR) > sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]); > else > @@ -1795,8 +1797,7 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) > ENTER(); > > for (; count; --count, ++epfile) { > - BUG_ON(mutex_is_locked(&epfile->mutex) || > - waitqueue_active(&epfile->wait)); > + BUG_ON(mutex_is_locked(&epfile->mutex)); > if (epfile->dentry) { > d_delete(epfile->dentry); > dput(epfile->dentry); > @@ -1883,11 +1884,11 @@ static int ffs_func_eps_enable(struct ffs_function *func) > break; > } > > - wake_up(&epfile->wait); > - > ++ep; > ++epfile; > } > + > + wake_up_interruptible(&ffs->wait); > spin_unlock_irqrestore(&func->ffs->eps_lock, flags); > > return ret; > diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h > index 4b6969451cdc..052ea89c7f99 100644 > --- a/drivers/usb/gadget/function/u_fs.h > +++ b/drivers/usb/gadget/function/u_fs.h > @@ -214,6 +214,9 @@ struct ffs_data { > #define FFS_FL_CALL_CLOSED_CALLBACK 0 > #define FFS_FL_BOUND 1 > > + /* For waking up blocked threads when function is enabled. */ > + wait_queue_head_t wait; > + > /* Active function */ > struct ffs_function *func; -- Best regards ミハウ “𝓶𝓲𝓷𝓪86” ナザレヴイツ «If at first you don’t succeed, give up skydiving» -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html