[PATCH 2/2] drm/ttm: optimize ttm_mem_evict_first v4
Michel Dänzer
michel at daenzer.net
Tue Nov 14 15:35:23 UTC 2017
On 14/11/17 01:18 PM, Christian König wrote:
> Am 14.11.2017 um 11:02 schrieb Michel Dänzer:
>> On 13/11/17 10:54 AM, Christian König wrote:
>>>
>>> + } else {
>>> + locked = reservation_object_trylock(bo->resv);
>>> + if (!locked)
>>> + continue;
>>> + }
>>> if (place && !bdev->driver->eviction_valuable(bo,
>>> place)) {
>>> - reservation_object_unlock(bo->resv);
>>> - ret = -EBUSY;
>>> + if (locked)
>>> + reservation_object_unlock(bo->resv);
>> I think we need to always set bo = NULL before continue, otherwise we
>> can end up trying to evict the very last BO even though we didn't
>> consider it suitable for eviction (and if
>> bdev->driver->eviction_valuable returned false, with locked = true even
>> though we already unlocked bo->resv).
>>
>>
>>> - if (!ret)
>>> + if (&bo->lru != &man->lru[i])
>> I'm not sure what the purpose of this test is, can you explain?
>
> It prevents the case you described above.
>
> bo is the element variable of the loop, so we can't set it to NULL
> inside the loop.
Yeah, that was a brainfart. :)
> Instead we check after the loop if we reached the end of the list, if
> yes we set the bo variable to NULL, otherwise we have found a valid
> entry and can break out of the for loop.
>
> To make it clearer we could also test "i" after the outer loop instead
> of bo for being NULL. That would at least be easier to understand I think.
That would still require detecting early termination of the inner loop
and breaking out of the outer loop, so it doesn't buy anything.
The clearest solution might be:
for (i = 0; !bo && i < TTM_MAX_BO_PRIORITY; ++i) {
struct ttm_buffer_object *candidate;
list_for_each_entry(candidate, &man->lru[i], lru) {
[if/continue using candidate instead of bo]
bo = candidate;
break;
}
}
if (!bo) {
[...]
Alternatively, this might clarify the test for early termination:
/* If the inner loop terminated early, we have our candidate */
if (&bo->lru != &man->lru[i])
break;
bo = NULL;
}
(could even move the bo = NULL to the end of the outer loop's for ()
line)
I'll leave it up to you which you choose, either way
Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer at amd.com>
--
Earthling Michel Dänzer | http://www.amd.com
Libre software enthusiast | Mesa and X developer
More information about the amd-gfx
mailing list