Hi Muchun, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on tj-cgroup/for-next] [also build test WARNING on linus/master v5.15-rc1] [cannot apply to hnaz-mm/master next-20210917] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Muchun-Song/Use-obj_cgroup-APIs-to-charge-the-LRU-pages/20210916-215452 base: https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git for-next config: i386-randconfig-s002-20210916 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce: # apt-get install sparse # sparse version: v0.6.4-dirty # https://github.com/0day-ci/linux/commit/a91949623178a5b2ef32a0842f6b6bae02a1a696 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Muchun-Song/Use-obj_cgroup-APIs-to-charge-the-LRU-pages/20210916-215452 git checkout a91949623178a5b2ef32a0842f6b6bae02a1a696 # save the attached .config to linux build tree make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot sparse warnings: (new ones prefixed by >>) mm/memcontrol.c:4227:21: sparse: sparse: incompatible types in comparison expression (different address spaces): mm/memcontrol.c:4227:21: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu * mm/memcontrol.c:4227:21: sparse: struct mem_cgroup_threshold_ary * mm/memcontrol.c:4229:21: sparse: sparse: incompatible types in comparison expression (different address spaces): mm/memcontrol.c:4229:21: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu * mm/memcontrol.c:4229:21: sparse: struct mem_cgroup_threshold_ary * mm/memcontrol.c:4385:9: sparse: sparse: incompatible types in comparison expression (different address spaces): mm/memcontrol.c:4385:9: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu * mm/memcontrol.c:4385:9: sparse: struct mem_cgroup_threshold_ary * mm/memcontrol.c:4479:9: sparse: sparse: incompatible types in comparison expression (different address spaces): mm/memcontrol.c:4479:9: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu * mm/memcontrol.c:4479:9: sparse: struct mem_cgroup_threshold_ary * >> mm/memcontrol.c:5832:26: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct obj_cgroup *objcg @@ got struct obj_cgroup [noderef] __rcu *objcg @@ mm/memcontrol.c:5833:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct obj_cgroup *objcg @@ got struct obj_cgroup [noderef] __rcu *objcg @@ mm/memcontrol.c:6128:23: sparse: sparse: incompatible types in comparison expression (different address spaces): mm/memcontrol.c:6128:23: sparse: struct task_struct [noderef] __rcu * mm/memcontrol.c:6128:23: sparse: struct task_struct * mm/memcontrol.c: note: in included file: include/linux/memcontrol.h:760:9: sparse: sparse: context imbalance in 'memcg_reparent_lruvec_lock' - wrong count at exit include/linux/memcontrol.h:760:9: sparse: sparse: context imbalance in 'memcg_reparent_lruvec_unlock' - unexpected unlock mm/memcontrol.c: note: in included file (through include/linux/rculist.h, include/linux/pid.h, include/linux/sched.h, ...): include/linux/rcupdate.h:718:9: sparse: sparse: context imbalance in 'lock_page_lruvec' - wrong count at exit include/linux/rcupdate.h:718:9: sparse: sparse: context imbalance in 'lock_page_lruvec_irq' - wrong count at exit include/linux/rcupdate.h:718:9: sparse: sparse: context imbalance in 'lock_page_lruvec_irqsave' - wrong count at exit mm/memcontrol.c:2109:6: sparse: sparse: context imbalance in 'lock_page_memcg' - wrong count at exit mm/memcontrol.c:2160:17: sparse: sparse: context imbalance in '__unlock_page_memcg' - unexpected unlock vim +5832 mm/memcontrol.c 5730 5731 /** 5732 * mem_cgroup_move_account - move account of the page 5733 * @page: the page 5734 * @compound: charge the page as compound or small page 5735 * @from: mem_cgroup which the page is moved from. 5736 * @to: mem_cgroup which the page is moved to. @from != @to. 5737 * 5738 * The caller must make sure the page is not on LRU (isolate_page() is useful.) 5739 * 5740 * This function doesn't do "charge" to new cgroup and doesn't do "uncharge" 5741 * from old cgroup. 5742 */ 5743 static int mem_cgroup_move_account(struct page *page, 5744 bool compound, 5745 struct mem_cgroup *from, 5746 struct mem_cgroup *to) 5747 { 5748 struct lruvec *from_vec, *to_vec; 5749 struct pglist_data *pgdat; 5750 unsigned int nr_pages = compound ? thp_nr_pages(page) : 1; 5751 int ret; 5752 5753 VM_BUG_ON(from == to); 5754 VM_BUG_ON_PAGE(PageLRU(page), page); 5755 VM_BUG_ON(compound && !PageTransHuge(page)); 5756 5757 /* 5758 * Prevent mem_cgroup_migrate() from looking at 5759 * page's memory cgroup of its source page while we change it. 5760 */ 5761 ret = -EBUSY; 5762 if (!trylock_page(page)) 5763 goto out; 5764 5765 ret = -EINVAL; 5766 if (page_memcg(page) != from) 5767 goto out_unlock; 5768 5769 pgdat = page_pgdat(page); 5770 from_vec = mem_cgroup_lruvec(from, pgdat); 5771 to_vec = mem_cgroup_lruvec(to, pgdat); 5772 5773 lock_page_memcg(page); 5774 5775 if (PageAnon(page)) { 5776 if (page_mapped(page)) { 5777 __mod_lruvec_state(from_vec, NR_ANON_MAPPED, -nr_pages); 5778 __mod_lruvec_state(to_vec, NR_ANON_MAPPED, nr_pages); 5779 if (PageTransHuge(page)) { 5780 __mod_lruvec_state(from_vec, NR_ANON_THPS, 5781 -nr_pages); 5782 __mod_lruvec_state(to_vec, NR_ANON_THPS, 5783 nr_pages); 5784 } 5785 } 5786 } else { 5787 __mod_lruvec_state(from_vec, NR_FILE_PAGES, -nr_pages); 5788 __mod_lruvec_state(to_vec, NR_FILE_PAGES, nr_pages); 5789 5790 if (PageSwapBacked(page)) { 5791 __mod_lruvec_state(from_vec, NR_SHMEM, -nr_pages); 5792 __mod_lruvec_state(to_vec, NR_SHMEM, nr_pages); 5793 } 5794 5795 if (page_mapped(page)) { 5796 __mod_lruvec_state(from_vec, NR_FILE_MAPPED, -nr_pages); 5797 __mod_lruvec_state(to_vec, NR_FILE_MAPPED, nr_pages); 5798 } 5799 5800 if (PageDirty(page)) { 5801 struct address_space *mapping = page_mapping(page); 5802 5803 if (mapping_can_writeback(mapping)) { 5804 __mod_lruvec_state(from_vec, NR_FILE_DIRTY, 5805 -nr_pages); 5806 __mod_lruvec_state(to_vec, NR_FILE_DIRTY, 5807 nr_pages); 5808 } 5809 } 5810 } 5811 5812 if (PageWriteback(page)) { 5813 __mod_lruvec_state(from_vec, NR_WRITEBACK, -nr_pages); 5814 __mod_lruvec_state(to_vec, NR_WRITEBACK, nr_pages); 5815 } 5816 5817 /* 5818 * All state has been migrated, let's switch to the new memcg. 5819 * 5820 * It is safe to change page's memcg here because the page 5821 * is referenced, charged, isolated, and locked: we can't race 5822 * with (un)charging, migration, LRU putback, or anything else 5823 * that would rely on a stable page's memory cgroup. 5824 * 5825 * Note that lock_page_memcg is a memcg lock, not a page lock, 5826 * to save space. As soon as we switch page's memory cgroup to a 5827 * new memcg that isn't locked, the above state can change 5828 * concurrently again. Make sure we're truly done with it. 5829 */ 5830 smp_mb(); 5831 > 5832 obj_cgroup_get(to->objcg); 5833 obj_cgroup_put(from->objcg); 5834 5835 page->memcg_data = (unsigned long)to->objcg; 5836 5837 __unlock_page_memcg(from); 5838 5839 ret = 0; 5840 5841 local_irq_disable(); 5842 mem_cgroup_charge_statistics(to, page, nr_pages); 5843 memcg_check_events(to, page); 5844 mem_cgroup_charge_statistics(from, page, -nr_pages); 5845 memcg_check_events(from, page); 5846 local_irq_enable(); 5847 out_unlock: 5848 unlock_page(page); 5849 out: 5850 return ret; 5851 } 5852 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org