7474#include <linux/dept.h>
7575#include <linux/utsname.h>
7676#include <linux/sched/task_stack.h>
77+ #include <linux/workqueue.h>
78+ #include <linux/irq_work.h>
7779#include "dept_internal.h"
7880
7981static int dept_stop ;
@@ -122,9 +124,11 @@ static int dept_per_cpu_ready;
122124 WARN(1, "DEPT_STOP: " s); \
123125 })
124126
125- #define DEPT_INFO_ONCE (s ...) pr_warn_once("DEPT_INFO_ONCE: " s)
127+ #define DEPT_INFO_ONCE (s ...) pr_warn_once("DEPT_INFO_ONCE: " s)
128+ #define DEPT_INFO (s ...) pr_warn("DEPT_INFO: " s)
126129
127130static arch_spinlock_t dept_spin = (arch_spinlock_t )__ARCH_SPIN_LOCK_UNLOCKED ;
131+ static arch_spinlock_t dept_pool_spin = (arch_spinlock_t )__ARCH_SPIN_LOCK_UNLOCKED ;
128132
129133/*
130134 * DEPT internal engine should be careful in using outside functions
@@ -244,6 +248,7 @@ static inline bool dept_working(void)
244248
245249#define OBJECT (id , nr ) \
246250static struct dept_##id spool_##id[nr]; \
251+ static struct dept_##id rpool_##id[nr]; \
247252static DEFINE_PER_CPU(struct llist_head, lpool_##id);
248253 #include "dept_object.h"
249254#undef OBJECT
@@ -252,14 +257,70 @@ struct dept_pool dept_pool[OBJECT_NR] = {
252257#define OBJECT (id , nr ) { \
253258 .name = #id , \
254259 .obj_sz = sizeof(struct dept_##id), \
255- .obj_nr = ATOMIC_INIT(nr), \
260+ .obj_nr = nr, \
261+ .tot_nr = nr, \
262+ .acc_sz = ATOMIC_INIT(sizeof(spool_##id) + sizeof(rpool_##id)), \
256263 .node_off = offsetof(struct dept_##id, pool_node), \
257264 .spool = spool_##id, \
265+ .rpool = rpool_##id, \
258266 .lpool = &lpool_##id, },
259267 #include "dept_object.h"
260268#undef OBJECT
261269};
262270
271+ static void dept_wq_work_fn (struct work_struct * work )
272+ {
273+ int i ;
274+
275+ for (i = 0 ; i < OBJECT_NR ; i ++ ) {
276+ struct dept_pool * p = dept_pool + i ;
277+ int sz = p -> tot_nr * p -> obj_sz ;
278+ void * rpool ;
279+ bool need ;
280+
281+ arch_spin_lock (& dept_pool_spin );
282+ need = !p -> rpool ;
283+ arch_spin_unlock (& dept_pool_spin );
284+
285+ if (!need )
286+ continue ;
287+
288+ rpool = kmalloc (sz , GFP_KERNEL );
289+
290+ if (!rpool ) {
291+ DEPT_STOP ("Failed to extend internal resources.\n" );
292+ break ;
293+ }
294+
295+ arch_spin_lock (& dept_pool_spin );
296+ if (!p -> rpool ) {
297+ p -> rpool = rpool ;
298+ rpool = NULL ;
299+ atomic_add (sz , & p -> acc_sz );
300+ }
301+ arch_spin_unlock (& dept_pool_spin );
302+
303+ if (rpool )
304+ kfree (rpool );
305+ else
306+ DEPT_INFO ("Dept object(%s) just got refilled successfully.\n" , p -> name );
307+ }
308+ }
309+
310+ static DECLARE_WORK (dept_wq_work , dept_wq_work_fn ) ;
311+
312+ static void dept_irq_work_fn (struct irq_work * w )
313+ {
314+ schedule_work (& dept_wq_work );
315+ }
316+
317+ static DEFINE_IRQ_WORK (dept_irq_work , dept_irq_work_fn ) ;
318+
319+ static void request_rpool_refill (void )
320+ {
321+ irq_work_queue (& dept_irq_work );
322+ }
323+
263324/*
264325 * Can use llist no matter whether CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG is
265326 * enabled or not because NMI and other contexts in the same CPU never
@@ -295,19 +356,31 @@ static void *from_pool(enum object_t t)
295356 /*
296357 * Try static pool.
297358 */
298- if (atomic_read (& p -> obj_nr ) > 0 ) {
299- int idx = atomic_dec_return (& p -> obj_nr );
359+ arch_spin_lock (& dept_pool_spin );
360+
361+ if (!p -> obj_nr ) {
362+ p -> spool = p -> rpool ;
363+ p -> obj_nr = p -> rpool ? p -> tot_nr : 0 ;
364+ p -> rpool = NULL ;
365+ request_rpool_refill ();
366+ }
367+
368+ if (p -> obj_nr ) {
369+ void * ret ;
370+
371+ p -> obj_nr -- ;
372+ ret = p -> spool + (p -> obj_nr * p -> obj_sz );
373+ arch_spin_unlock (& dept_pool_spin );
300374
301- if (idx >= 0 )
302- return p -> spool + (idx * p -> obj_sz );
375+ return ret ;
303376 }
377+ arch_spin_unlock (& dept_pool_spin );
304378
305- DEPT_INFO_ONCE ("---------------------------------------------\n"
306- " Some of Dept internal resources are run out.\n"
307- " Dept might still work if the resources get freed.\n"
308- " However, the chances are Dept will suffer from\n"
309- " the lack from now. Needs to extend the internal\n"
310- " resource pools. Ask max.byungchul.park@gmail.com\n" );
379+ DEPT_INFO ("------------------------------------------\n"
380+ " Dept object(%s) is run out.\n"
381+ " Dept is trying to refill the object.\n"
382+ " Nevertheless, if it fails, Dept will stop.\n" ,
383+ p -> name );
311384 return NULL ;
312385}
313386
@@ -2964,15 +3037,15 @@ void __init dept_init(void)
29643037 pr_info ("... DEPT_MAX_ECXT_HELD : %d\n" , DEPT_MAX_ECXT_HELD );
29653038 pr_info ("... DEPT_MAX_SUBCLASSES : %d\n" , DEPT_MAX_SUBCLASSES );
29663039#define OBJECT (id , nr ) \
2967- pr_info("... memory used by %s: %zu KB\n", \
2968- #id, B2KB(sizeof(struct dept_ ##id) * nr ));
3040+ pr_info("... memory initially used by %s: %zu KB\n", \
3041+ #id, B2KB(sizeof(spool_ ##id) + sizeof(rpool_##id) ));
29693042 #include "dept_object.h"
29703043#undef OBJECT
29713044#define HASH (id , bits ) \
29723045 pr_info("... hash list head used by %s: %zu KB\n", \
29733046 #id, B2KB(sizeof(struct hlist_head) * (1UL << bits)));
29743047 #include "dept_hash.h"
29753048#undef HASH
2976- pr_info ("... total memory used by objects and hashs: %zu KB\n" , B2KB (mem_total ));
3049+ pr_info ("... total memory initially used by objects and hashs: %zu KB\n" , B2KB (mem_total ));
29773050 pr_info ("... per task memory footprint: %zu bytes\n" , sizeof (struct dept_task ));
29783051}
0 commit comments