On Thu, Aug 22, 2019 at 03:56:14PM +0530, Bharata B Rao wrote:
> +/*
> + * Bits 60:56 in the rmap entry will be used to identify the
> + * different uses/functions of rmap.
> + */
> +#define KVMPPC_RMAP_DEVM_PFN (0x2ULL << 56)

How did you come up with this specific value?

> +
> +static inline bool kvmppc_rmap_is_devm_pfn(unsigned long pfn)
> +{
> +     return !!(pfn & KVMPPC_RMAP_DEVM_PFN);
> +}

No need for !! when returning a bool.  Also the helper seems a little
pointless, just opencoding it would make the code more readable in my
opinion.

> +#ifdef CONFIG_PPC_UV
> +extern int kvmppc_devm_init(void);
> +extern void kvmppc_devm_free(void);

There is no need for extern in a function declaration.

> +static int
> +kvmppc_devm_migrate_alloc_and_copy(struct migrate_vma *mig,
> +                                unsigned long *rmap, unsigned long gpa,
> +                                unsigned int lpid, unsigned long page_shift)
> +{
> +     struct page *spage = migrate_pfn_to_page(*mig->src);
> +     unsigned long pfn = *mig->src >> MIGRATE_PFN_SHIFT;
> +     struct page *dpage;
> +
> +     *mig->dst = 0;
> +     if (!spage || !(*mig->src & MIGRATE_PFN_MIGRATE))
> +             return 0;
> +
> +     dpage = kvmppc_devm_get_page(rmap, gpa, lpid);
> +     if (!dpage)
> +             return -EINVAL;
> +
> +     if (spage)
> +             uv_page_in(lpid, pfn << page_shift, gpa, 0, page_shift);
> +
> +     *mig->dst = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
> +     return 0;
> +}

I think you can just merge this trivial helper into the only caller.

> +static int
> +kvmppc_devm_fault_migrate_alloc_and_copy(struct migrate_vma *mig,
> +                                      unsigned long page_shift)
> +{
> +     struct page *dpage, *spage;
> +     struct kvmppc_devm_page_pvt *pvt;
> +     unsigned long pfn;
> +     int ret;
> +
> +     spage = migrate_pfn_to_page(*mig->src);
> +     if (!spage || !(*mig->src & MIGRATE_PFN_MIGRATE))
> +             return 0;
> +     if (!is_zone_device_page(spage))
> +             return 0;
> +
> +     dpage = alloc_page_vma(GFP_HIGHUSER, mig->vma, mig->start);
> +     if (!dpage)
> +             return -EINVAL;
> +     lock_page(dpage);
> +     pvt = spage->zone_device_data;
> +
> +     pfn = page_to_pfn(dpage);
> +     ret = uv_page_out(pvt->lpid, pfn << page_shift, pvt->gpa, 0,
> +                       page_shift);
> +     if (ret == U_SUCCESS)
> +             *mig->dst = migrate_pfn(pfn) | MIGRATE_PFN_LOCKED;
> +     else {
> +             unlock_page(dpage);
> +             __free_page(dpage);
> +     }
> +     return ret;
> +}

Here we actually have two callers, but they have a fair amount of
duplicate code in them.  I think you want to move that common
code (including setting up the migrate_vma structure) into this
function and maybe also give it a more descriptive name.

> +static void kvmppc_devm_page_free(struct page *page)
> +{
> +     unsigned long pfn = page_to_pfn(page);
> +     unsigned long flags;
> +     struct kvmppc_devm_page_pvt *pvt;
> +
> +     spin_lock_irqsave(&kvmppc_devm_pfn_lock, flags);
> +     pvt = page->zone_device_data;
> +     page->zone_device_data = NULL;
> +
> +     bitmap_clear(kvmppc_devm_pfn_bitmap,
> +                  pfn - (kvmppc_devm_pgmap.res.start >> PAGE_SHIFT), 1);

Nit: I'd just initialize pfn to the value you want from the start.
That makes the code a little easier to read, and keeps a tiny bit more
code outside the spinlock.

        unsigned long pfn = page_to_pfn(page) -
                        (kvmppc_devm_pgmap.res.start >> PAGE_SHIFT);

        ..

         bitmap_clear(kvmppc_devm_pfn_bitmap, pfn, 1);


> +     kvmppc_devm_pgmap.type = MEMORY_DEVICE_PRIVATE;
> +     kvmppc_devm_pgmap.res = *res;
> +     kvmppc_devm_pgmap.ops = &kvmppc_devm_ops;
> +     addr = memremap_pages(&kvmppc_devm_pgmap, -1);

This -1 should be NUMA_NO_NODE for clarity.

Reply via email to