@@ -336,7 +336,7 @@ enum oom_scan_t oom_scan_process_thread(struct task_struct *task,
336
336
337
337
/*
338
338
* Simple selection loop. We chose the process with the highest
339
- * number of 'points'. We expect the caller will lock the tasklist.
339
+ * number of 'points'.
340
340
*
341
341
* (not docbooked, we don't want this one cluttering up the manual)
342
342
*/
@@ -348,6 +348,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
348
348
struct task_struct * chosen = NULL ;
349
349
unsigned long chosen_points = 0 ;
350
350
351
+ rcu_read_lock ();
351
352
do_each_thread (g , p ) {
352
353
unsigned int points ;
353
354
@@ -360,6 +361,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
360
361
case OOM_SCAN_CONTINUE :
361
362
continue ;
362
363
case OOM_SCAN_ABORT :
364
+ rcu_read_unlock ();
363
365
return ERR_PTR (-1UL );
364
366
case OOM_SCAN_OK :
365
367
break ;
@@ -370,6 +372,9 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
370
372
chosen_points = points ;
371
373
}
372
374
} while_each_thread (g , p );
375
+ if (chosen )
376
+ get_task_struct (chosen );
377
+ rcu_read_unlock ();
373
378
374
379
* ppoints = chosen_points * 1000 / totalpages ;
375
380
return chosen ;
@@ -385,15 +390,14 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
385
390
* are not shown.
386
391
* State information includes task's pid, uid, tgid, vm size, rss, nr_ptes,
387
392
* swapents, oom_score_adj value, and name.
388
- *
389
- * Call with tasklist_lock read-locked.
390
393
*/
391
394
static void dump_tasks (const struct mem_cgroup * memcg , const nodemask_t * nodemask )
392
395
{
393
396
struct task_struct * p ;
394
397
struct task_struct * task ;
395
398
396
399
pr_info ("[ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name\n" );
400
+ rcu_read_lock ();
397
401
for_each_process (p ) {
398
402
if (oom_unkillable_task (p , memcg , nodemask ))
399
403
continue ;
@@ -416,6 +420,7 @@ static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemas
416
420
task -> signal -> oom_score_adj , task -> comm );
417
421
task_unlock (task );
418
422
}
423
+ rcu_read_unlock ();
419
424
}
420
425
421
426
static void dump_header (struct task_struct * p , gfp_t gfp_mask , int order ,
@@ -436,6 +441,10 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
436
441
}
437
442
438
443
#define K (x ) ((x) << (PAGE_SHIFT-10))
444
+ /*
445
+ * Must be called while holding a reference to p, which will be released upon
446
+ * returning.
447
+ */
439
448
void oom_kill_process (struct task_struct * p , gfp_t gfp_mask , int order ,
440
449
unsigned int points , unsigned long totalpages ,
441
450
struct mem_cgroup * memcg , nodemask_t * nodemask ,
@@ -455,6 +464,7 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
455
464
*/
456
465
if (p -> flags & PF_EXITING ) {
457
466
set_tsk_thread_flag (p , TIF_MEMDIE );
467
+ put_task_struct (p );
458
468
return ;
459
469
}
460
470
@@ -472,6 +482,7 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
472
482
* parent. This attempts to lose the minimal amount of work done while
473
483
* still freeing memory.
474
484
*/
485
+ read_lock (& tasklist_lock );
475
486
do {
476
487
list_for_each_entry (child , & t -> children , sibling ) {
477
488
unsigned int child_points ;
@@ -484,15 +495,26 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
484
495
child_points = oom_badness (child , memcg , nodemask ,
485
496
totalpages );
486
497
if (child_points > victim_points ) {
498
+ put_task_struct (victim );
487
499
victim = child ;
488
500
victim_points = child_points ;
501
+ get_task_struct (victim );
489
502
}
490
503
}
491
504
} while_each_thread (p , t );
505
+ read_unlock (& tasklist_lock );
492
506
493
- victim = find_lock_task_mm (victim );
494
- if (!victim )
507
+ rcu_read_lock ();
508
+ p = find_lock_task_mm (victim );
509
+ if (!p ) {
510
+ rcu_read_unlock ();
511
+ put_task_struct (victim );
495
512
return ;
513
+ } else if (victim != p ) {
514
+ get_task_struct (p );
515
+ put_task_struct (victim );
516
+ victim = p ;
517
+ }
496
518
497
519
/* mm cannot safely be dereferenced after task_unlock(victim) */
498
520
mm = victim -> mm ;
@@ -523,9 +545,11 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
523
545
task_unlock (p );
524
546
do_send_sig_info (SIGKILL , SEND_SIG_FORCED , p , true);
525
547
}
548
+ rcu_read_unlock ();
526
549
527
550
set_tsk_thread_flag (victim , TIF_MEMDIE );
528
551
do_send_sig_info (SIGKILL , SEND_SIG_FORCED , victim , true);
552
+ put_task_struct (victim );
529
553
}
530
554
#undef K
531
555
@@ -546,9 +570,7 @@ static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask,
546
570
if (constraint != CONSTRAINT_NONE )
547
571
return ;
548
572
}
549
- read_lock (& tasklist_lock );
550
573
dump_header (NULL , gfp_mask , order , NULL , nodemask );
551
- read_unlock (& tasklist_lock );
552
574
panic ("Out of memory: %s panic_on_oom is enabled\n" ,
553
575
sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide" );
554
576
}
@@ -721,10 +743,10 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
721
743
mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY ) ? nodemask : NULL ;
722
744
check_panic_on_oom (constraint , gfp_mask , order , mpol_mask );
723
745
724
- read_lock (& tasklist_lock );
725
746
if (sysctl_oom_kill_allocating_task && current -> mm &&
726
747
!oom_unkillable_task (current , NULL , nodemask ) &&
727
748
current -> signal -> oom_score_adj != OOM_SCORE_ADJ_MIN ) {
749
+ get_task_struct (current );
728
750
oom_kill_process (current , gfp_mask , order , 0 , totalpages , NULL ,
729
751
nodemask ,
730
752
"Out of memory (oom_kill_allocating_task)" );
@@ -735,7 +757,6 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
735
757
/* Found nothing?!?! Either we hang forever, or we panic. */
736
758
if (!p ) {
737
759
dump_header (NULL , gfp_mask , order , NULL , mpol_mask );
738
- read_unlock (& tasklist_lock );
739
760
panic ("Out of memory and no killable processes...\n" );
740
761
}
741
762
if (PTR_ERR (p ) != -1UL ) {
@@ -744,8 +765,6 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
744
765
killed = 1 ;
745
766
}
746
767
out :
747
- read_unlock (& tasklist_lock );
748
-
749
768
/*
750
769
* Give the killed threads a good chance of exiting before trying to
751
770
* allocate memory again.
0 commit comments