@@ -464,6 +464,20 @@ static void nv_mem_pool_shrinker_register(nv_page_pool_t *mem_pool, struct shrin
464464}
465465#endif // NV_SHRINKER_ALLOC_PRESENT
466466
467+ // Pages in the pool are reclaimable non-slab kernel memory. Tracking them
468+ // with NR_KERNEL_MISC_RECLAIMABLE lets si_mem_available() include them in
469+ // MemAvailable (/proc/meminfo), giving the kernel an accurate picture of how
470+ // much memory can be recovered under pressure via the registered shrinker.
471+ static void nv_mem_pool_mod_misc_reclaimable (nv_page_pool_t * mem_pool , long delta_compound_pages )
472+ {
473+ #if defined(NV_NR_KERNEL_MISC_RECLAIMABLE_PRESENT )
474+ if (delta_compound_pages != 0 )
475+ mod_node_page_state (NODE_DATA (mem_pool -> node_id ),
476+ NR_KERNEL_MISC_RECLAIMABLE ,
477+ delta_compound_pages << mem_pool -> order );
478+ #endif
479+ }
480+
467481static unsigned long
468482nv_mem_pool_move_pages
469483(
@@ -561,6 +575,8 @@ nv_mem_pool_shrinker_scan
561575 mem_pool -> pages_owned -= pages_freed ;
562576 os_release_mutex (mem_pool -> lock );
563577
578+ nv_mem_pool_mod_misc_reclaimable (mem_pool , - (long )pages_freed );
579+
564580 nv_mem_pool_free_page_list (& reclaim_list , mem_pool -> order );
565581
566582 nv_printf (NV_DBG_MEMINFO , "NVRM: VM: %s: node=%d order=%u: %lu/%lu pages freed\n" ,
@@ -619,6 +635,8 @@ nv_mem_pool_alloc_pages
619635 pages_owned = mem_pool -> pages_owned ;
620636 os_release_mutex (mem_pool -> lock );
621637
638+ nv_mem_pool_mod_misc_reclaimable (mem_pool , - (long )pages_allocated );
639+
622640 while ((pool_entry = NV_MEM_POOL_LIST_HEAD (& alloc_clean_pages )))
623641 {
624642 nv_alloc_set_page (at , i , pool_entry -> virt_addr );
@@ -691,9 +709,12 @@ void
691709nv_mem_pool_destroy (nv_page_pool_t * mem_pool )
692710{
693711 NV_STATUS status ;
712+ unsigned long saved_pages_owned ;
694713
695714 status = os_acquire_mutex (mem_pool -> lock );
696715 WARN_ON (status != NV_OK );
716+ // Snapshot before freeing: counts dirty + in-flight + clean pages.
717+ saved_pages_owned = mem_pool -> pages_owned ;
697718 nv_mem_pool_free_page_list (& mem_pool -> dirty_list , mem_pool -> order );
698719 os_release_mutex (mem_pool -> lock );
699720
@@ -706,6 +727,8 @@ nv_mem_pool_destroy(nv_page_pool_t *mem_pool)
706727 nv_mem_pool_free_page_list (& mem_pool -> clean_list , mem_pool -> order );
707728 os_release_mutex (mem_pool -> lock );
708729
730+ nv_mem_pool_mod_misc_reclaimable (mem_pool , - (long )saved_pages_owned );
731+
709732 nv_mem_pool_shrinker_free (mem_pool );
710733
711734 os_free_mutex (mem_pool -> lock );
@@ -832,8 +855,12 @@ nv_mem_pool_free_pages
832855 pages_owned = mem_pool -> pages_owned ;
833856 os_release_mutex (mem_pool -> lock );
834857
835- nv_printf (NV_DBG_MEMINFO , "NVRM: VM: %s: node=%d order=%u: %lu/%lu pages added to pool (%lu now in pool)\n" ,
836- __FUNCTION__ , mem_pool -> node_id , mem_pool -> order , num_added_pages , num_pages , pages_owned );
858+ nv_mem_pool_mod_misc_reclaimable (mem_pool , (long )num_added_pages );
859+
860+ nv_printf (NV_DBG_MEMINFO , "NVRM: VM: %s: at = %lx, at->order = %u, at->num_pages = %u, \
861+ pool_order = %u: %lu/%lu pages added to pool (%lu now in pool)\n" , \
862+ __FUNCTION__ , (long int ) at , at -> order , at -> num_pages , mem_pool -> order , \
863+ num_added_pages , num_pages , pages_owned );
837864
838865 if (queue_worker )
839866 {
@@ -1122,6 +1149,35 @@ static NvUPtr nv_vmap(struct page **pages, NvU32 page_count,
11221149 return (NvUPtr )ptr ;
11231150}
11241151
1152+ NvU64 nv_get_reclaimable_memory_usage (void )
1153+ {
1154+ int node_id ;
1155+ unsigned int order ;
1156+ NvU64 reclaimable_memory_bytes = 0 ;
1157+
1158+ for_each_node (node_id )
1159+ {
1160+ for (order = 0 ; order <= NV_MAX_PAGE_ORDER ; order ++ )
1161+ {
1162+ if (sysmem_page_pools [node_id ][order ])
1163+ {
1164+ nv_printf (NV_DBG_MEMINFO , "NVRM: VM: %s: node_id = %u, pool_order = %u: %lu pages in pool\n" , \
1165+ __FUNCTION__ , node_id , sysmem_page_pools [node_id ][order ]-> order , \
1166+ sysmem_page_pools [node_id ][order ]-> pages_owned );
1167+
1168+ reclaimable_memory_bytes += (sysmem_page_pools [node_id ][order ]-> pages_owned \
1169+ << sysmem_page_pools [node_id ][order ]-> order ) \
1170+ * PAGE_SIZE ;
1171+
1172+ nv_printf (NV_DBG_MEMINFO , "NVRM: VM: %s: reclaimable_memory_bytes = %d\n" , \
1173+ __FUNCTION__ , reclaimable_memory_bytes );
1174+ }
1175+ }
1176+ }
1177+
1178+ return reclaimable_memory_bytes ;
1179+ }
1180+
11251181static void nv_vunmap (NvUPtr vaddr , NvU32 page_count )
11261182{
11271183 vunmap ((void * )vaddr );
0 commit comments