On 11/27/18 2:53 AM, Benny Halevy wrote: >> @@ -818,11 +853,15 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, >> { >> struct kioctx_table *table; >> >> + mutex_lock(&ctx->getevents_lock); >> spin_lock(&mm->ioctx_lock); >> if (atomic_xchg(&ctx->dead, 1)) { >> spin_unlock(&mm->ioctx_lock); >> + mutex_unlock(&ctx->getevents_lock); >> return -EINVAL; >> } >> + aio_iopoll_reap_events(ctx); >> + mutex_unlock(&ctx->getevents_lock); > > Is it worth handling the mutex lock and calling aio_iopoll_reap_events > only if (ctx->flags & IOCTX_FLAG_IOPOLL)? If so, testing it can be > removed from aio_iopoll_reap_events() (and maybe it could even > be open coded > here since this is its only call site apparently) I don't think it really matters, this only happens when you tear down an io_context. FWIW, I think it's cleaner to retain the test in the function, not outside it. >> @@ -1072,6 +1112,15 @@ static inline void iocb_put(struct aio_kiocb *iocb) >> } >> } >> >> +static void iocb_put_many(struct kioctx *ctx, void **iocbs, int *nr) >> +{ >> + if (nr) { > > How can nr by NULL? > And what's the point of supporting this case? > Did you mean: if (*nr)? > (In this case, if safe to call the functions below with *nr==0, > I'm not sure it's worth optimizing... especially since this is a static > function and its callers make sure to call it only when *nr > 0) Indeed, that should be if (*nr), thanks! The slub implementation of the bulk free complains if you pass in nr == 0. Outside of that, a single check should be better than checking in multiple spots. >> @@ -1261,6 +1310,166 @@ static bool aio_read_events(struct kioctx *ctx, long min_nr, long nr, >> return ret < 0 || *i >= min_nr; >> } >> >> +#define AIO_IOPOLL_BATCH 8 >> + >> +/* >> + * Process completed iocb iopoll entries, copying the result to userspace. >> + */ >> +static long aio_iopoll_reap(struct kioctx *ctx, struct io_event __user *evs, >> + unsigned int *nr_events, long max) >> +{ >> + void *iocbs[AIO_IOPOLL_BATCH]; >> + struct aio_kiocb *iocb, *n; >> + int to_free = 0, ret = 0; >> + >> + list_for_each_entry_safe(iocb, n, &ctx->poll_completing, ki_list) { >> + if (*nr_events == max) > > *nr_events >= max would be safer. I don't see how we can get there with it being larger than already, that would be a big bug if we fill more events than userspace asked for. >> @@ -1570,17 +1829,43 @@ static inline void aio_rw_done(struct kiocb *req, ssize_t ret) >> default: >> req->ki_complete(req, ret, 0); >> } >> + > > nit: this hunk is probably unintentional Looks like it, I'll kill it. -- Jens Axboe