3434#include "nvmap_priv.h"
3535
3636#define NVMAP_TEST_PAGE_POOL_SHRINKER 1
37- #define PENDING_PAGES_SIZE 128
38- #define MIN_AVAILABLE_MB 128
37+ #define PENDING_PAGES_SIZE 32
3938
4039static bool enable_pp = 1 ;
4140static int pool_size ;
4241
4342static struct task_struct * background_allocator ;
4443static DECLARE_WAIT_QUEUE_HEAD (nvmap_bg_wait );
4544static struct page * pending_pages [PENDING_PAGES_SIZE ];
46- static atomic_t bg_pages_to_fill ;
4745
4846#ifdef CONFIG_NVMAP_PAGE_POOL_DEBUG
4947static inline void __pp_dbg_var_add (u64 * dbg_var , u32 nr )
@@ -62,6 +60,21 @@ static inline void __pp_dbg_var_add(u64 *dbg_var, u32 nr)
6260static int __nvmap_page_pool_fill_lots_locked (struct nvmap_page_pool * pool ,
6361 struct page * * pages , u32 nr );
6462
63+ static inline struct page * get_zero_list_page (struct nvmap_page_pool * pool )
64+ {
65+ struct page * page ;
66+
67+ if (list_empty (& pool -> zero_list ))
68+ return NULL ;
69+
70+ page = list_first_entry (& pool -> zero_list , struct page , lru );
71+ list_del (& page -> lru );
72+
73+ pool -> to_zero -- ;
74+
75+ return page ;
76+ }
77+
6578static inline struct page * get_page_list_page (struct nvmap_page_pool * pool )
6679{
6780 struct page * page ;
@@ -82,81 +95,50 @@ static inline bool nvmap_bg_should_run(struct nvmap_page_pool *pool)
8295 bool ret ;
8396
8497 mutex_lock (& pool -> lock );
85- ret = (pool -> to_zero > 0 || atomic_read ( & bg_pages_to_fill ) );
98+ ret = (pool -> to_zero > 0 );
8699 mutex_unlock (& pool -> lock );
87100
88101 return ret ;
89102}
90103
91- /*
92- * Allocate n pages one by one. Not the most efficient allocation scheme ever;
93- * however, it will make it easier later on to handle single or small number of
94- * page allocations from the page pool being individually freed.
95- */
96- static int __nvmap_pp_alloc_n_pages (struct page * * pages , int n , gfp_t flags )
104+ static int nvmap_pp_zero_pages (struct page * * pages , int nr )
97105{
98106 int i ;
99107
100- for (i = 0 ; i < n ; i ++ ) {
101- pages [i ] = alloc_page (flags );
102- if (!pages [i ])
103- goto no_mem ;
104- }
108+ for (i = 0 ; i < nr ; i ++ )
109+ clear_highpage (pages [i ]);
105110
106111 return 0 ;
107-
108- no_mem :
109- for (i -= 1 ; i >= 0 ; i -- )
110- __free_page (pages [i ]);
111- return - ENOMEM ;
112112}
113113
114- /*
115- * Actually do the fill. This requires a few steps:
116- *
117- * 1. Allocate a bunch of pages.
118- *
119- * 2. Fill the page pool with the allocated pages. We don't want to hold the
120- * PP lock for too long so this is the only time we hold the PP lock.
121- *
122- * 3. Rinse and repeat until we have allocated all the pages we think we need
123- * or the page pool is full. Since we are not holding the lock for the
124- * entire fill it is possible that other pages were filled into the pool.
125- *
126- * 4. Free any left over pages if the pool is filled before we finish.
127- */
128- static void nvmap_pp_do_background_fill (struct nvmap_page_pool * pool )
114+ static void nvmap_pp_do_background_zero_pages (struct nvmap_page_pool * pool )
129115{
130- int err ;
131- u32 pages = 0 , nr , i ;
132- gfp_t gfp = GFP_NVMAP | __GFP_NOMEMALLOC |
133- __GFP_NORETRY | __GFP_NO_KSWAPD ;
134-
135- pages = (u32 )atomic_xchg (& bg_pages_to_fill , pages );
136-
137- if (!pages || !enable_pp )
138- return ;
116+ int i ;
117+ struct page * page ;
118+ int ret ;
139119
140- /* If this param is set, force zero page allocation. */
141- if (zero_memory )
142- gfp |= __GFP_ZERO ;
120+ mutex_lock (& pool -> lock );
121+ for (i = 0 ; i < PENDING_PAGES_SIZE ; i ++ ) {
122+ page = get_zero_list_page (pool );
123+ if (page == NULL )
124+ break ;
125+ pending_pages [i ] = page ;
126+ }
127+ mutex_unlock (& pool -> lock );
143128
144- do {
145- nr = min_t (u32 , PENDING_PAGES_SIZE , pages );
146- err = __nvmap_pp_alloc_n_pages (pending_pages , nr , gfp );
147- if (err ) {
148- pr_info ("Failed to alloc %u pages for PP!\n" , pages );
149- return ;
150- }
129+ ret = nvmap_pp_zero_pages (pending_pages , i );
130+ if (ret < 0 ) {
131+ ret = 0 ;
132+ goto out ;
133+ }
151134
152- mutex_lock (& pool -> lock );
153- i = __nvmap_page_pool_fill_lots_locked (pool , pending_pages , nr );
154- mutex_unlock (& pool -> lock );
155- pages -= nr ;
156- } while (pages && i == nr );
135+ mutex_lock (& pool -> lock );
136+ ret = __nvmap_page_pool_fill_lots_locked (pool , pending_pages , i );
137+ mutex_unlock (& pool -> lock );
157138
158- for (; i < nr ; i ++ )
159- __free_page (pending_pages [i ]);
139+ out :
140+ for (; ret < i ; ret ++ )
141+ __free_page (pending_pages [ret ]);
160142}
161143
162144/*
@@ -167,18 +149,20 @@ static void nvmap_pp_do_background_fill(struct nvmap_page_pool *pool)
167149 * not directly seen by userspace. Of course if the page pools are empty user
168150 * space will suffer.
169151 */
170- static int nvmap_background_zero_allocator (void * arg )
152+ static int nvmap_background_zero_thread (void * arg )
171153{
172154 struct nvmap_page_pool * pool = & nvmap_dev -> pool ;
173155 struct sched_param param = { .sched_priority = 0 };
174156
175- pr_info ("PP alloc thread starting.\n" );
157+ pr_info ("PP zeroing thread starting.\n" );
176158
177159 set_freezable ();
178160 sched_setscheduler (current , SCHED_IDLE , & param );
179161
180162 while (!kthread_should_stop ()) {
181- nvmap_pp_do_background_fill (pool );
163+ while (nvmap_bg_should_run (pool )) {
164+ nvmap_pp_do_background_zero_pages (pool );
165+ }
182166
183167 wait_event_freezable (nvmap_bg_wait ,
184168 nvmap_bg_should_run (pool ) ||
@@ -188,44 +172,6 @@ static int nvmap_background_zero_allocator(void *arg)
188172 return 0 ;
189173}
190174
191- /*
192- * Call this if the background allocator should possibly wake up. This function
193- * will check to make sure its actually a good idea for that to happen before
194- * waking the allocator up.
195- */
196- static inline void nvmap_pp_wake_up_allocator (void )
197- {
198- struct nvmap_page_pool * pool = & nvmap_dev -> pool ;
199- struct sysinfo info ;
200- int free_pages , tmp ;
201-
202- if (!enable_pp )
203- return ;
204-
205- /* Hueristic: if we don't need to prefill explicitly zero'ed memory then
206- * lots of memory can be placed back in the pools by possible frees.
207- * Therefor don't fill the pool unless we really need to as we may get
208- * more memory without needing to alloc pages.
209- */
210- if (!zero_memory && pool -> count > NVMAP_PP_ZERO_MEM_FILL_MIN )
211- return ;
212-
213- if (pool -> max - pool -> count < NVMAP_PP_DEF_FILL_THRESH )
214- return ;
215-
216- si_meminfo (& info );
217- free_pages = (int )info .freeram ;
218-
219- tmp = free_pages - (MIN_AVAILABLE_MB << (20 - PAGE_SHIFT ));
220- if (tmp <= 0 )
221- return ;
222-
223- /* Let the background thread know how much memory to fill. */
224- atomic_set (& bg_pages_to_fill ,
225- min (tmp , (int )(pool -> max - pool -> count )));
226- wake_up_interruptible (& nvmap_bg_wait );
227- }
228-
229175/*
230176 * This removes a page from the page pool. If ignore_disable is set, then
231177 * the enable_pp flag is ignored.
@@ -295,7 +241,6 @@ static int __nvmap_page_pool_alloc_lots_locked(struct nvmap_page_pool *pool,
295241 pp_alloc_add (pool , ind );
296242 pp_hit_add (pool , ind );
297243 pp_miss_add (pool , nr - ind );
298- nvmap_pp_wake_up_allocator ();
299244
300245 return ind ;
301246}
@@ -312,33 +257,6 @@ int nvmap_page_pool_alloc_lots(struct nvmap_page_pool *pool,
312257 return ret ;
313258}
314259
315- /*
316- * This adds a page to the pool. Returns true if the passed page is added.
317- * That means if the pool is full this operation will fail.
318- */
319- static bool nvmap_page_pool_fill_locked (struct nvmap_page_pool * pool ,
320- struct page * page )
321- {
322- if (!enable_pp )
323- return false;
324-
325- if (pool -> count >= pool -> max )
326- return false;
327-
328- /* Sanity check. */
329- if (IS_ENABLED (CONFIG_NVMAP_PAGE_POOL_DEBUG )) {
330- atomic_inc (& page -> _count );
331- BUG_ON (atomic_read (& page -> _count ) != 2 );
332- BUG_ON (pool -> count > pool -> max );
333- }
334-
335- list_add_tail (& page -> lru , & pool -> page_list );
336- pool -> count ++ ;
337- pp_fill_add (pool , 1 );
338-
339- return true;
340- }
341-
342260/*
343261 * Fill a bunch of pages into the page pool. This will fill as many as it can
344262 * and return the number of pages filled. Pages are used from the start of the
@@ -379,21 +297,23 @@ int nvmap_page_pool_fill_lots(struct nvmap_page_pool *pool,
379297 int ret ;
380298
381299 mutex_lock (& pool -> lock );
382- ret = __nvmap_page_pool_fill_lots_locked ( pool , pages , nr );
383- mutex_unlock ( & pool -> lock ) ;
300+ if ( zero_memory ) {
301+ int i ;
384302
385- return ret ;
386- }
303+ nr = min (nr , pool -> max - pool -> count - pool -> to_zero );
387304
388- bool nvmap_page_pool_fill (struct nvmap_page_pool * pool , struct page * page )
389- {
390- bool ret = false;
305+ for (i = 0 ; i < nr ; i ++ ) {
306+ list_add_tail (& pages [i ]-> lru , & pool -> zero_list );
307+ pool -> to_zero ++ ;
308+ }
391309
392- if (pool ) {
393- mutex_lock (& pool -> lock );
394- ret = nvmap_page_pool_fill_locked (pool , page );
395- mutex_unlock (& pool -> lock );
310+ wake_up_interruptible (& nvmap_bg_wait );
311+
312+ ret = i ;
313+ } else {
314+ ret = __nvmap_page_pool_fill_lots_locked (pool , pages , nr );
396315 }
316+ mutex_unlock (& pool -> lock );
397317
398318 return ret ;
399319}
@@ -413,7 +333,9 @@ static int nvmap_page_pool_free(struct nvmap_page_pool *pool, int nr_free)
413333
414334 mutex_lock (& pool -> lock );
415335 while (i ) {
416- page = nvmap_page_pool_alloc_locked (pool , 1 );
336+ page = get_zero_list_page (pool );
337+ if (!page )
338+ page = nvmap_page_pool_alloc_locked (pool , 1 );
417339 if (!page )
418340 break ;
419341 __free_page (page );
@@ -431,7 +353,7 @@ ulong nvmap_page_pool_get_unused_pages(void)
431353 if (!nvmap_dev )
432354 return 0 ;
433355
434- total = nvmap_dev -> pool .count ;
356+ total = nvmap_dev -> pool .count + nvmap_dev -> pool . to_zero ;
435357
436358 return total ;
437359}
@@ -450,14 +372,18 @@ int nvmap_page_pool_clear(void)
450372 while ((page = nvmap_page_pool_alloc_locked (pool , 1 )) != NULL )
451373 __free_page (page );
452374
375+ while (!list_empty (& pool -> zero_list )) {
376+ page = get_zero_list_page (pool );
377+ __free_page (page );
378+ }
379+
453380 /* For some reason, if an error occured... */
454- if (!list_empty (& pool -> page_list )) {
381+ if (!list_empty (& pool -> page_list ) || ! list_empty ( & pool -> zero_list ) ) {
455382 mutex_unlock (& pool -> lock );
456383 return - ENOMEM ;
457384 }
458385
459386 mutex_unlock (& pool -> lock );
460- nvmap_pp_wake_up_allocator ();
461387
462388 return 0 ;
463389}
@@ -610,6 +536,9 @@ int nvmap_page_pool_debugfs_init(struct dentry *nvmap_root)
610536 debugfs_create_u32 ("page_pool_available_pages" ,
611537 S_IRUGO , pp_root ,
612538 & nvmap_dev -> pool .count );
539+ debugfs_create_u32 ("page_pool_pages_to_zero" ,
540+ S_IRUGO , pp_root ,
541+ & nvmap_dev -> pool .to_zero );
613542#ifdef CONFIG_NVMAP_PAGE_POOL_DEBUG
614543 debugfs_create_u64 ("page_pool_allocs" ,
615544 S_IRUGO , pp_root ,
@@ -630,14 +559,14 @@ int nvmap_page_pool_debugfs_init(struct dentry *nvmap_root)
630559
631560int nvmap_page_pool_init (struct nvmap_device * dev )
632561{
633- static int reg = 1 ;
634562 unsigned long totalram_mb ;
635563 struct sysinfo info ;
636564 struct nvmap_page_pool * pool = & dev -> pool ;
637565
638566 memset (pool , 0x0 , sizeof (* pool ));
639567 mutex_init (& pool -> lock );
640568 INIT_LIST_HEAD (& pool -> page_list );
569+ INIT_LIST_HEAD (& pool -> zero_list );
641570
642571 si_meminfo (& info );
643572 totalram_mb = (info .totalram * info .mem_unit ) >> 20 ;
@@ -656,16 +585,13 @@ int nvmap_page_pool_init(struct nvmap_device *dev)
656585 pr_info ("nvmap page pool size: %u pages (%u MB)\n" , pool -> max ,
657586 (pool -> max * info .mem_unit ) >> 20 );
658587
659- if (reg ) {
660- reg = 0 ;
661- register_shrinker (& nvmap_page_pool_shrinker );
662- }
663-
664- background_allocator = kthread_create (nvmap_background_zero_allocator ,
588+ background_allocator = kthread_run (nvmap_background_zero_thread ,
665589 NULL , "nvmap-bz" );
666590 if (IS_ERR_OR_NULL (background_allocator ))
667591 goto fail ;
668592
593+ register_shrinker (& nvmap_page_pool_shrinker );
594+
669595 return 0 ;
670596fail :
671597 nvmap_page_pool_fini (dev );
0 commit comments