> -----Original Message----- > From: Coly Li <colyli@xxxxxxx> > Sent: Wednesday, December 16, 2020 6:30 PM > To: Ren, Qiaowei <qiaowei.ren@xxxxxxxxx> > Cc: linux-bcache@xxxxxxxxxxxxxxx; Ma, Jianpeng <jianpeng.ma@xxxxxxxxx> > Subject: Re: [RFC PATCH 3/8] bcache: initialization of the buddy > > 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. > In func init_owner_info, we already remove the alloced space. Thanks! Jianpeng. > > [snipped] > > Coly Li