Merge tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull hmm updates from Jason Gunthorpe: "This series adds a selftest for hmm_range_fault() and several of the DEVICE_PRIVATE migration related actions, and another simplification for hmm_range_fault()'s API. - Simplify hmm_range_fault() with a simpler return code, no HMM_PFN_SPECIAL, and no customizable output PFN format - Add a selftest for hmm_range_fault() and DEVICE_PRIVATE related functionality" * tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: MAINTAINERS: add HMM selftests mm/hmm/test: add selftests for HMM mm/hmm/test: add selftest driver for HMM mm/hmm: remove the customizable pfn format from hmm_range_fault mm/hmm: remove HMM_PFN_SPECIAL drm/amdgpu: remove dead code after hmm_range_fault() mm/hmm: make hmm_range_fault return 0 or -1
This commit is contained in:
@@ -161,7 +161,7 @@ device must complete the update before the driver callback returns.
|
||||
When the device driver wants to populate a range of virtual addresses, it can
|
||||
use::
|
||||
|
||||
long hmm_range_fault(struct hmm_range *range);
|
||||
int hmm_range_fault(struct hmm_range *range);
|
||||
|
||||
It will trigger a page fault on missing or read-only entries if write access is
|
||||
requested (see below). Page faults use the generic mm page fault code path just
|
||||
@@ -184,10 +184,7 @@ The usage pattern is::
|
||||
range.notifier = &interval_sub;
|
||||
range.start = ...;
|
||||
range.end = ...;
|
||||
range.pfns = ...;
|
||||
range.flags = ...;
|
||||
range.values = ...;
|
||||
range.pfn_shift = ...;
|
||||
range.hmm_pfns = ...;
|
||||
|
||||
if (!mmget_not_zero(interval_sub->notifier.mm))
|
||||
return -EFAULT;
|
||||
@@ -229,15 +226,10 @@ The hmm_range struct has 2 fields, default_flags and pfn_flags_mask, that specif
|
||||
fault or snapshot policy for the whole range instead of having to set them
|
||||
for each entry in the pfns array.
|
||||
|
||||
For instance, if the device flags for range.flags are::
|
||||
For instance if the device driver wants pages for a range with at least read
|
||||
permission, it sets::
|
||||
|
||||
range.flags[HMM_PFN_VALID] = (1 << 63);
|
||||
range.flags[HMM_PFN_WRITE] = (1 << 62);
|
||||
|
||||
and the device driver wants pages for a range with at least read permission,
|
||||
it sets::
|
||||
|
||||
range->default_flags = (1 << 63);
|
||||
range->default_flags = HMM_PFN_REQ_FAULT;
|
||||
range->pfn_flags_mask = 0;
|
||||
|
||||
and calls hmm_range_fault() as described above. This will fill fault all pages
|
||||
@@ -246,18 +238,18 @@ in the range with at least read permission.
|
||||
Now let's say the driver wants to do the same except for one page in the range for
|
||||
which it wants to have write permission. Now driver set::
|
||||
|
||||
range->default_flags = (1 << 63);
|
||||
range->pfn_flags_mask = (1 << 62);
|
||||
range->pfns[index_of_write] = (1 << 62);
|
||||
range->default_flags = HMM_PFN_REQ_FAULT;
|
||||
range->pfn_flags_mask = HMM_PFN_REQ_WRITE;
|
||||
range->pfns[index_of_write] = HMM_PFN_REQ_WRITE;
|
||||
|
||||
With this, HMM will fault in all pages with at least read (i.e., valid) and for the
|
||||
address == range->start + (index_of_write << PAGE_SHIFT) it will fault with
|
||||
write permission i.e., if the CPU pte does not have write permission set then HMM
|
||||
will call handle_mm_fault().
|
||||
|
||||
Note that HMM will populate the pfns array with write permission for any page
|
||||
that is mapped with CPU write permission no matter what values are set
|
||||
in default_flags or pfn_flags_mask.
|
||||
After hmm_range_fault completes the flag bits are set to the current state of
|
||||
the page tables, ie HMM_PFN_VALID | HMM_PFN_WRITE will be set if the page is
|
||||
writable.
|
||||
|
||||
|
||||
Represent and manage device memory from core kernel point of view
|
||||
|
Reference in New Issue
Block a user