Jason Gunthorpe <jgg@xxxxxxxxxx> writes: > On Tue, Jan 24, 2023 at 04:42:35PM +1100, Alistair Popple wrote: >> diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c >> index c301b3b..250276e 100644 >> --- a/drivers/infiniband/hw/usnic/usnic_uiom.c >> +++ b/drivers/infiniband/hw/usnic/usnic_uiom.c >> @@ -89,8 +89,6 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, >> struct page **page_list; >> struct scatterlist *sg; >> struct usnic_uiom_chunk *chunk; >> - unsigned long locked; >> - unsigned long lock_limit; >> unsigned long cur_base; >> unsigned long npages; >> int ret; >> @@ -123,10 +121,8 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, >> uiomr->owning_mm = mm = current->mm; >> mmap_read_lock(mm); >> >> - locked = atomic64_add_return(npages, ¤t->mm->pinned_vm); >> - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; >> - >> - if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) { >> + vm_account_init_current(&uiomr->vm_account); >> + if (vm_account_pinned(&uiomr->vm_account, npages)) { >> ret = -ENOMEM; >> goto out; >> } > > Is this error handling right? This driver tried to avoid the race by > using atomic64_add_return() but it means that the out label undoes the add: > > >> @@ -178,7 +174,8 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, >> out: >> if (ret < 0) { >> usnic_uiom_put_pages(chunk_list, 0); >> - atomic64_sub(npages, ¤t->mm->pinned_vm); > > Here > >> + vm_unaccount_pinned(&uiomr->vm_account, npages); >> + vm_account_release(&uiomr->vm_account); > > But with the new API we shouldn't call vm_unaccount_pinned() if > vm_account_pinned() doesn't succeed? Good point. Will add the following fix: @@ -123,6 +123,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, vm_account_init_current(&uiomr->vm_account); if (vm_account_pinned(&uiomr->vm_account, npages)) { + npages = 0; ret = -ENOMEM; goto out; } > > Jason