On 12/3/20 6:53 PM, Qiaowei Ren wrote: > This nvm pages allocator will implement the simple buddy to manage the > nvm address space. This patch initializes this buddy for new namespace. > > the unit of alloc/free of the buddy is page. DAX device has their > struct page(in dram or PMEM). > > struct { /* ZONE_DEVICE pages */ > /** @pgmap: Points to the hosting device page map. */ > struct dev_pagemap *pgmap; > void *zone_device_data; > /* > * ZONE_DEVICE private pages are counted as being > * mapped so the next 3 words hold the mapping, index, > * and private fields from the source anonymous or > * page cache page while the page is migrated to device > * private memory. > * ZONE_DEVICE MEMORY_DEVICE_FS_DAX pages also > * use the mapping, index, and private fields when > * pmem backed DAX files are mapped. > */ > }; > > ZONE_DEVICE pages only use pgmap. Other 4 words[16/32 bytes] don't use. > So the second/third word will be used as 'struct list_head ' which list > in buddy. The fourth word(that is normal struct page::index) store pgoff > which the page-offset in the dax device. And the fifth word (that is > normal struct page::private) store order of buddy. page_type will be used > to store buddy flags. > > Signed-off-by: Jianpeng Ma <jianpeng.ma@xxxxxxxxx> > Signed-off-by: Qiaowei Ren <qiaowei.ren@xxxxxxxxx> > --- > drivers/md/bcache/nvm-pages.c | 68 ++++++++++++++++++++++++++++++++++- > drivers/md/bcache/nvm-pages.h | 3 ++ > 2 files changed, 70 insertions(+), 1 deletion(-) > > diff --git a/drivers/md/bcache/nvm-pages.c b/drivers/md/bcache/nvm-pages.c > index 841616ea3267..7ffbfbacaf3f 100644 > --- a/drivers/md/bcache/nvm-pages.c > +++ b/drivers/md/bcache/nvm-pages.c > @@ -84,6 +84,17 @@ static void *nvm_pgoff_to_vaddr(struct nvm_namespace *ns, pgoff_t pgoff) > return ns->kaddr + ns->pages_offset + (pgoff << PAGE_SHIFT); > } > > +static struct page *nvm_vaddr_to_page(struct nvm_namespace *ns, void *addr) > +{ > + return virt_to_page(addr); > +} > + > +static inline void remove_owner_space(struct nvm_namespace *ns, > + pgoff_t pgoff, u32 nr) > +{ > + bitmap_set(ns->pages_bitmap, pgoff, nr); > +} > + > static void init_owner_info(struct nvm_namespace *ns) > { > struct owner_list_head *owner_list_head; > @@ -126,6 +137,8 @@ static void init_owner_info(struct nvm_namespace *ns) > extent->nr = rec->nr; > list_add_tail(&extent->list, &extents->extent_head); > > + remove_owner_space(extents->ns, rec->pgoff, rec->nr); > + > extents->ns->free -= rec->nr; > } > extents->size += nvm_pgalloc_recs->size; > @@ -143,6 +156,54 @@ static void init_owner_info(struct nvm_namespace *ns) > mutex_unlock(&only_set->lock); > } > > +static void init_nvm_free_space(struct nvm_namespace *ns) > +{ > + unsigned int start, end, i; > + struct page *page; > + unsigned int pages; > + pgoff_t pgoff_start; > + > + bitmap_for_each_clear_region(ns->pages_bitmap, start, end, 0, ns->pages_total) { > + pgoff_start = start; > + pages = end - start; > + > + while (pages) { > + for (i = MAX_ORDER - 1; i >= 0 ; i--) { > + if ((start % (1 << i) == 0) && (pages >= (1 << i))) > + break; > + } > + > + page = nvm_vaddr_to_page(ns, nvm_pgoff_to_vaddr(ns, pgoff_start)); > + page->index = pgoff_start; > + page->private = i; > + __SetPageBuddy(page); > + list_add((struct list_head *)&page->zone_device_data, &ns->free_area[i]); > + > + pgoff_start += 1 << i; > + pages -= 1 << i; > + } > + } > + > + bitmap_for_each_set_region(ns->pages_bitmap, start, end, 0, ns->pages_total) { > + pages = end - start; > + pgoff_start = start; > + > + while (pages) { > + for (i = MAX_ORDER - 1; i >= 0 ; i--) { > + if ((start % (1 << i) == 0) && (pages >= (1 << i))) > + break; > + } > + > + page = nvm_vaddr_to_page(ns, nvm_pgoff_to_vaddr(ns, pgoff_start)); > + page->index = pgoff_start; > + page->private = i; > + > + pgoff_start += 1 << i; > + pages -= 1 << i; > + } > + } > +} > + The buddy structure should be initialized from the owner lists, we cannot assume the name space is empty. Because the user space may also allocate space from NVDIMM even before the first time it is attached by kernel driver. [snipped] Coly Li