On 12/18/20 11:42 AM, Ira Weiny wrote:
Another problem would be if the kmap and kunmap happened in different contexts... :-/ I don't think that is done either but I don't know for certain.
It would be really nice to put together some surveillance patches to help become more certain about these things. Even a per-task counter would be better than nothing.
On kmap: current->kmaps++; On kunmap: current->kmaps--; WARN_ON(current->kmaps < 0); On exit: WARN_ON(current->kmaps);
That would at least find imbalances. You could take it even further by having a little array, say:
struct one_kmap { struct page *page; depot_stack_handle_t handle; };
Then:
struct task_struct { ... + struct one_kmap kmaps[10]; };
On kmap() you make a new entry in current->kmaps[], and on kunmap() you try to find the corresponding entry. If you can't find one, in the current task you can even go search all the other tasks and see who might be responsible. If something goes and does more than 10 simultaneous kmap()s in one thread, dump a warning and give up. Or, dynamically allocate the kmaps[] array.
Then you can dump out the stack of the kmap() culprit if it exits after a kmap() but without a corresponding kfree().
Something like that should be low overhead enough to get it into things like the 0day debug kernel. It should be way cheaper than something like lockdep.