Re: [PATCH v2] RDMA/umem: minor bug fix and cleanup in error handling paths

From: John Hubbard
Date: Mon Mar 04 2019 - 18:11:09 EST


On 3/3/19 8:55 AM, Ira Weiny wrote:
> On Sun, Mar 03, 2019 at 11:52:41AM +0200, Artemy Kovalyov wrote:
>>
>>
>> On 02/03/2019 21:44, Ira Weiny wrote:
>>>
>>> On Sat, Mar 02, 2019 at 12:24:35PM -0800, john.hubbard@xxxxxxxxx wrote:
>>>> From: John Hubbard <jhubbard@xxxxxxxxxx>
>>>>
>>>> ...
>>>> 3. Dead code removal: the check for (user_virt & ~page_mask)
>>>> is checking for a condition that can never happen,
>>>> because earlier:
>>>>
>>>> user_virt = user_virt & page_mask;
>>>>
>>>> ...so, remove that entire phrase.
>>>>
>>>> bcnt -= min_t(size_t, npages << PAGE_SHIFT, bcnt);
>>>> mutex_lock(&umem_odp->umem_mutex);
>>>> for (j = 0; j < npages; j++, user_virt += PAGE_SIZE) {
>>>> - if (user_virt & ~page_mask) {
>>>> - p += PAGE_SIZE;
>>>> - if (page_to_phys(local_page_list[j]) != p) {
>>>> - ret = -EFAULT;
>>>> - break;
>>>> - }
>>>> - put_page(local_page_list[j]);
>>>> - continue;
>>>> - }
>>>> -
>>>
>>> I think this is trying to account for compound pages. (ie page_mask could
>>> represent more than PAGE_SIZE which is what user_virt is being incrimented by.)
>>> But putting the page in that case seems to be the wrong thing to do?
>>>
>>> Yes this was added by Artemy[1] now cc'ed.
>>
>> Right, this is for huge pages, please keep it.
>> put_page() needed to decrement refcount of the head page.
>
> You mean decrement the refcount of the _non_-head pages?
>
> Ira
>

Actually, I'm sure Artemy means head page, because put_page() always
operates on the head page.

And this reminds me that I have a problem to solve nearby: get_user_pages
on huge pages increments the page->_refcount *for each tail page* as well.
That's a minor problem for my put_user_page()
patchset, because my approach so far assumed that I could just change us
over to:

get_user_page(): increments page->_refcount by a large amount (1024)

put_user_page(): decrements page->_refcount by a large amount (1024)

...and just stop doing the odd (to me) technique of incrementing once for
each tail page. I cannot see any reason why that's actually required, as
opposed to just "raise the page->_refcount enough to avoid losing the head
page too soon".

However, it may be tricky to do this in one pass. Probably at first, I'll have
to do this horrible thing approach:

get_user_page(): increments page->_refcount by a large amount (1024)

put_user_page(): decrements page->_refcount by a large amount (1024) MULTIPLIED
by the number of tail pages. argghhh that's ugly.

thanks,
--
John Hubbard
NVIDIA