If the freeing queue has many objects, freeing all of them consecutively may cause soft lockup especially on a debug kernel. So kmem_free_up_q() is modified to call cond_resched() if running in the process context. Signed-off-by: Waiman Long <longman@xxxxxxxxxx> --- mm/slab_common.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mm/slab_common.c b/mm/slab_common.c index dba20b4208f1..633a1d0f6d20 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1622,11 +1622,14 @@ EXPORT_SYMBOL_GPL(kmem_free_q_add); * kmem_free_up_q - free all the objects in the freeing queue * @head: freeing queue head * - * Free all the objects in the freeing queue. + * Free all the objects in the freeing queue. The caller cannot hold any + * non-sleeping locks. */ void kmem_free_up_q(struct kmem_free_q_head *head) { struct kmem_free_q_node *node, *next; + bool do_resched = !in_irq(); + int cnt = 0; for (node = head->first; node; node = next) { next = node->next; @@ -1634,6 +1637,12 @@ void kmem_free_up_q(struct kmem_free_q_head *head) kmem_cache_free(node->cachep, node); else kfree(node); + /* + * Call cond_resched() every 256 objects freed when in + * process context. + */ + if (do_resched && !(++cnt & 0xff)) + cond_resched(); } } EXPORT_SYMBOL_GPL(kmem_free_up_q); -- 2.18.1