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

Reply via email to