summaryrefslogtreecommitdiffstats
path: root/lib/debugobjects.c
diff options
context:
space:
mode:
authorWaiman Long <longman@redhat.com>2019-05-20 10:14:48 -0400
committerThomas Gleixner <tglx@linutronix.de>2019-06-14 08:51:15 -0400
commitd26bf5056fc087d845bfbb8b651b4be2933ab7a6 (patch)
tree6a07feea9b2a5f39b0376a32de2dce01424f7b16 /lib/debugobjects.c
parent634d61f45d6f668fe7e468b62d00ae469a583ca2 (diff)
debugobjects: Reduce number of pool_lock acquisitions in fill_pool()
In fill_pool(), the pool_lock is acquired and then released once per debug object. If many objects are to be filled, the constant lock and unlock operations are extra overhead. To reduce the overhead, batch them up and do an allocation of 4 objects per lock/unlock sequence. Signed-off-by: Waiman Long <longman@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Yang Shi <yang.shi@linux.alibaba.com> Cc: "Joel Fernandes (Google)" <joel@joelfernandes.org> Cc: Qian Cai <cai@gmx.us> Cc: Zhong Jiang <zhongjiang@huawei.com> Link: https://lkml.kernel.org/r/20190520141450.7575-4-longman@redhat.com
Diffstat (limited to 'lib/debugobjects.c')
-rw-r--r--lib/debugobjects.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 714459a8dc10..7ea19fa63561 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -120,7 +120,7 @@ static const char *obj_states[ODEBUG_STATE_MAX] = {
120static void fill_pool(void) 120static void fill_pool(void)
121{ 121{
122 gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; 122 gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
123 struct debug_obj *new, *obj; 123 struct debug_obj *obj;
124 unsigned long flags; 124 unsigned long flags;
125 125
126 if (likely(obj_pool_free >= debug_objects_pool_min_level)) 126 if (likely(obj_pool_free >= debug_objects_pool_min_level))
@@ -136,7 +136,7 @@ static void fill_pool(void)
136 * Recheck with the lock held as the worker thread might have 136 * Recheck with the lock held as the worker thread might have
137 * won the race and freed the global free list already. 137 * won the race and freed the global free list already.
138 */ 138 */
139 if (obj_nr_tofree) { 139 while (obj_nr_tofree && (obj_pool_free < obj_pool_min_free)) {
140 obj = hlist_entry(obj_to_free.first, typeof(*obj), node); 140 obj = hlist_entry(obj_to_free.first, typeof(*obj), node);
141 hlist_del(&obj->node); 141 hlist_del(&obj->node);
142 obj_nr_tofree--; 142 obj_nr_tofree--;
@@ -150,15 +150,23 @@ static void fill_pool(void)
150 return; 150 return;
151 151
152 while (obj_pool_free < debug_objects_pool_min_level) { 152 while (obj_pool_free < debug_objects_pool_min_level) {
153 struct debug_obj *new[ODEBUG_BATCH_SIZE];
154 int cnt;
153 155
154 new = kmem_cache_zalloc(obj_cache, gfp); 156 for (cnt = 0; cnt < ODEBUG_BATCH_SIZE; cnt++) {
155 if (!new) 157 new[cnt] = kmem_cache_zalloc(obj_cache, gfp);
158 if (!new[cnt])
159 break;
160 }
161 if (!cnt)
156 return; 162 return;
157 163
158 raw_spin_lock_irqsave(&pool_lock, flags); 164 raw_spin_lock_irqsave(&pool_lock, flags);
159 hlist_add_head(&new->node, &obj_pool); 165 while (cnt) {
160 debug_objects_allocated++; 166 hlist_add_head(&new[--cnt]->node, &obj_pool);
161 obj_pool_free++; 167 debug_objects_allocated++;
168 obj_pool_free++;
169 }
162 raw_spin_unlock_irqrestore(&pool_lock, flags); 170 raw_spin_unlock_irqrestore(&pool_lock, flags);
163 } 171 }
164} 172}
@@ -280,7 +288,7 @@ static void free_obj_work(struct work_struct *work)
280 /* 288 /*
281 * The objs on the pool list might be allocated before the work is 289 * The objs on the pool list might be allocated before the work is
282 * run, so recheck if pool list it full or not, if not fill pool 290 * run, so recheck if pool list it full or not, if not fill pool
283 * list from the global free list 291 * list from the global free list.
284 */ 292 */
285 while (obj_nr_tofree && obj_pool_free < debug_objects_pool_size) { 293 while (obj_nr_tofree && obj_pool_free < debug_objects_pool_size) {
286 obj = hlist_entry(obj_to_free.first, typeof(*obj), node); 294 obj = hlist_entry(obj_to_free.first, typeof(*obj), node);