Hi Huan,

> Subject: Re: [PATCH v5 4/7] udmabuf: udmabuf_create pin folio codestyle
> cleanup
> 
> 
> 在 2024/9/6 16:17, Kasireddy, Vivek 写道:
> > Hi Huan,
> >
> >> Subject: [PATCH v5 4/7] udmabuf: udmabuf_create pin folio codestyle
> >> cleanup
> >>
> >> This patch split pin folios into single function: udmabuf_pin_folios.
> >>
> >> When record folio and offset into udmabuf_folio and offsets, the outer
> >> loop of this patch iterates through folios, while the inner loop correctly
> >> sets the folio and corresponding offset into the udmabuf starting from
> >> the offset. if reach to pgcnt or nr_folios, end of loop.
> >>
> >> By this, more readable.
> >>
> >> Signed-off-by: Huan Yang <l...@vivo.com>
> >> ---
> >>   drivers/dma-buf/udmabuf.c | 132 ++++++++++++++++++++------------------
> >>   1 file changed, 71 insertions(+), 61 deletions(-)
> >>
> >> diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
> >> index 456db58446e1..ca2b21c5c57f 100644
> >> --- a/drivers/dma-buf/udmabuf.c
> >> +++ b/drivers/dma-buf/udmabuf.c
> >> @@ -330,17 +330,67 @@ static int export_udmabuf(struct udmabuf
> *ubuf,
> >>    return dma_buf_fd(buf, flags);
> >>   }
> >>
> >> +static int udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd,
> >> +                        loff_t start, loff_t size)
> >> +{
> >> +  pgoff_t pgoff, pgcnt, upgcnt = ubuf->pagecount;
> >> +  u32 cur_folio, cur_pgcnt;
> >> +  struct folio **folios = NULL;
> >> +  long nr_folios;
> >> +  loff_t end;
> >> +  int ret = 0;
> > Change ret's type and this function's return type to long for consistency.
> >
> >> +
> >> +  pgcnt = size >> PAGE_SHIFT;
> >> +  folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
> >> +  if (!folios)
> >> +          return -ENOMEM;
> >> +
> >> +  end = start + (pgcnt << PAGE_SHIFT) - 1;
> >> +  nr_folios = memfd_pin_folios(memfd, start, end, folios, pgcnt,
> >> &pgoff);
> >> +  if (nr_folios <= 0) {
> >> +          ret = nr_folios ? nr_folios : -EINVAL;
> >> +          goto err;
> >> +  }
> >> +
> >> +  cur_pgcnt = 0;
> >> +  for (cur_folio = 0; cur_folio < nr_folios; ++cur_folio) {
> >> +          pgoff_t subpgoff = pgoff;
> >> +          size_t fsize = folio_size(folios[cur_folio]);
> >> +
> >> +          ret = add_to_unpin_list(&ubuf->unpin_list, folios[cur_folio]);
> >> +          if (ret < 0)
> >> +                  goto err;
> >> +
> >> +          for (; subpgoff < fsize; subpgoff += PAGE_SIZE) {
> >> +                  ubuf->folios[upgcnt] = folios[cur_folio];
> >> +                  ubuf->offsets[upgcnt] = subpgoff;
> >> +                  ++upgcnt;
> >> +
> >> +                  if (++cur_pgcnt >= pgcnt)
> >> +                          goto end;
> >> +          }
> >> +
> >> +          /**
> >> +           * The term range may start with offset, so the first folio
> >> +           * need take care of it. And the remain folio start from 0.
> > The comments above are not very meaningful. Please rewrite them as:
> > * In a given range, only the first subpage of the first folio has an 
> > offset, that
> > * is returned by memfd_pin_folios(). The first subpages of other folios (in
> the
> > * range) have an offset of 0.
> >
> >> +           */
> >> +          pgoff = 0;
> >> +  }
> >> +end:
> >> +err:
> > No need to have two labels here. Keep end and get rid of err?
> >
> >> +  ubuf->pagecount = upgcnt;
> >> +  kvfree(folios);
> >> +  return ret;
> >> +}
> >> +
> >>   static long udmabuf_create(struct miscdevice *device,
> >>                       struct udmabuf_create_list *head,
> >>                       struct udmabuf_create_item *list)
> >>   {
> >> -  pgoff_t pgoff, pgcnt, pglimit, pgbuf = 0;
> >> -  long nr_folios, ret = -EINVAL;
> >> -  struct file *memfd = NULL;
> >> -  struct folio **folios;
> >> +  pgoff_t pgcnt = 0, pglimit;
> >> +  long ret = -EINVAL;
> >>    struct udmabuf *ubuf;
> >> -  u32 i, j, k, flags;
> >> -  loff_t end;
> >> +  u32 i, flags;
> >>
> >>    ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL);
> >>    if (!ubuf)
> >> @@ -349,81 +399,43 @@ static long udmabuf_create(struct miscdevice
> >> *device,
> >>    INIT_LIST_HEAD(&ubuf->unpin_list);
> >>    pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
> >>    for (i = 0; i < head->count; i++) {
> >> -          if (!IS_ALIGNED(list[i].offset, PAGE_SIZE))
> >> +          if (!PAGE_ALIGNED(list[i].offset))
> >>                    goto err;
> >> -          if (!IS_ALIGNED(list[i].size, PAGE_SIZE))
> >> +          if (!PAGE_ALIGNED(list[i].size))
> >>                    goto err;
> >> -          ubuf->pagecount += list[i].size >> PAGE_SHIFT;
> >> -          if (ubuf->pagecount > pglimit)
> >> +
> >> +          pgcnt += list[i].size >> PAGE_SHIFT;
> >> +          if (pgcnt > pglimit)
> >>                    goto err;
> >>    }
> >>
> >> -  if (!ubuf->pagecount)
> >> +  if (!pgcnt)
> >>            goto err;
> >>
> >> -  ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf-
> >>> folios),
> >> -                                GFP_KERNEL);
> >> +  ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios),
> >> GFP_KERNEL);
> >>    if (!ubuf->folios) {
> >>            ret = -ENOMEM;
> >>            goto err;
> >>    }
> >> -  ubuf->offsets = kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets),
> >> -                           GFP_KERNEL);
> >> +
> >> +  ubuf->offsets = kvcalloc(pgcnt, sizeof(*ubuf->offsets), GFP_KERNEL);
> >>    if (!ubuf->offsets) {
> >>            ret = -ENOMEM;
> >>            goto err;
> >>    }
> >>
> >> -  pgbuf = 0;
> >>    for (i = 0; i < head->count; i++) {
> >> -          memfd = fget(list[i].memfd);
> >> +          struct file *memfd = fget(list[i].memfd);
> >> +
> >>            ret = check_memfd_seals(memfd);
> >>            if (ret < 0)
> >>                    goto err;
> >>
> >> -          pgcnt = list[i].size >> PAGE_SHIFT;
> >> -          folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
> >> -          if (!folios) {
> >> -                  ret = -ENOMEM;
> >> -                  goto err;
> >> -          }
> >> -
> >> -          end = list[i].offset + (pgcnt << PAGE_SHIFT) - 1;
> >> -          ret = memfd_pin_folios(memfd, list[i].offset, end,
> >> -                                 folios, pgcnt, &pgoff);
> >> -          if (ret <= 0) {
> >> -                  kvfree(folios);
> >> -                  if (!ret)
> >> -                          ret = -EINVAL;
> >> -                  goto err;
> >> -          }
> >> -
> >> -          nr_folios = ret;
> >> -          pgoff >>= PAGE_SHIFT;
> >> -          for (j = 0, k = 0; j < pgcnt; j++) {
> >> -                  ubuf->folios[pgbuf] = folios[k];
> >> -                  ubuf->offsets[pgbuf] = pgoff << PAGE_SHIFT;
> >> -
> >> -                  if (j == 0 || ubuf->folios[pgbuf-1] != folios[k]) {
> >> -                          ret = add_to_unpin_list(&ubuf->unpin_list,
> >> -                                                  folios[k]);
> >> -                          if (ret < 0) {
> >> -                                  kfree(folios);
> >> -                                  goto err;
> >> -                          }
> >> -                  }
> >> -
> >> -                  pgbuf++;
> >> -                  if (++pgoff == folio_nr_pages(folios[k])) {
> >> -                          pgoff = 0;
> >> -                          if (++k == nr_folios)
> >> -                                  break;
> >> -                  }
> >> -          }
> >> -
> >> -          kvfree(folios);
> >> +          ret = udmabuf_pin_folios(ubuf, memfd, list[i].offset,
> >> +                                   list[i].size);
> >>            fput(memfd);
> >> -          memfd = NULL;
> >> +          if (ret)
> >> +                  goto err;
> >>    }
> >>
> >>    flags = head->flags & UDMABUF_FLAGS_CLOEXEC ? O_CLOEXEC : 0;
> >> @@ -434,8 +446,6 @@ static long udmabuf_create(struct miscdevice
> >> *device,
> >>    return ret;
> >>
> >>   err:
> >> -  if (memfd)
> >> -          fput(memfd);
> > I think this needs to stay because if the seals check fails, then we would 
> > not
> be
> > doing fput(memfd).
> 
> Yes, there a mistake, but I'd like set it into here:
> 
>               ret = check_memfd_seals(memfd);
>               if (ret < 0) {
You still need an if (memfd) check here because check_memfd_seals() might do:
        if (!memfd)
                return -EBADFD;

Thanks,
Vivek

>                       fput(memfd);
>                       goto err;
>               }
> due to only in inner look, memfd can get. and memfd change into loop var.
> Thanks
> 
> >
> > Thanks,
> > Vivek
> >
> >>    unpin_all_folios(&ubuf->unpin_list);
> >>    kvfree(ubuf->offsets);
> >>    kvfree(ubuf->folios);
> >> --
> >> 2.45.2

Reply via email to