Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

trace/osnoise: Support hotplug operations

Enable and disable osnoise/timerlat thread during on CPU hotplug online
and offline operations respectivelly.

Link: https://lore.kernel.org/linux-doc/20210621134636.5b332226@oasis.local.home/
Link: https://lkml.kernel.org/r/39f98590b3caeb3c32f09526214058efe0e9272a.1624372313.git.bristot@redhat.com

Cc: Phil Auld <pauld@redhat.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Kate Carcia <kcarcia@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Alexandre Chartre <alexandre.chartre@oracle.com>
Cc: Clark Willaims <williams@redhat.com>
Cc: John Kacur <jkacur@redhat.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Suggested-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Daniel Bristot de Oliveira <bristot@redhat.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>

authored by

Daniel Bristot de Oliveira and committed by
Steven Rostedt (VMware)
c8895e27 ba998f7d

+135 -30
+135 -30
kernel/trace/trace_osnoise.c
··· 1416 1416 #endif /* CONFIG_TIMERLAT_TRACER */ 1417 1417 1418 1418 /* 1419 - * stop_per_cpu_kthread - stop per-cpu threads 1419 + * stop_kthread - stop a workload thread 1420 + */ 1421 + static void stop_kthread(unsigned int cpu) 1422 + { 1423 + struct task_struct *kthread; 1424 + 1425 + kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread; 1426 + if (kthread) 1427 + kthread_stop(kthread); 1428 + per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; 1429 + } 1430 + 1431 + /* 1432 + * stop_per_cpu_kthread - Stop per-cpu threads 1420 1433 * 1421 1434 * Stop the osnoise sampling htread. Use this on unload and at system 1422 1435 * shutdown. 1423 1436 */ 1424 1437 static void stop_per_cpu_kthreads(void) 1425 1438 { 1426 - struct task_struct *kthread; 1427 1439 int cpu; 1428 1440 1429 - for_each_online_cpu(cpu) { 1430 - kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread; 1431 - if (kthread) 1432 - kthread_stop(kthread); 1433 - per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; 1441 + get_online_cpus(); 1442 + 1443 + for_each_online_cpu(cpu) 1444 + stop_kthread(cpu); 1445 + 1446 + put_online_cpus(); 1447 + } 1448 + 1449 + /* 1450 + * start_kthread - Start a workload tread 1451 + */ 1452 + static int start_kthread(unsigned int cpu) 1453 + { 1454 + struct task_struct *kthread; 1455 + void *main = osnoise_main; 1456 + char comm[24]; 1457 + 1458 + #ifdef CONFIG_TIMERLAT_TRACER 1459 + if (osnoise_data.timerlat_tracer) { 1460 + snprintf(comm, 24, "timerlat/%d", cpu); 1461 + main = timerlat_main; 1462 + } else { 1463 + snprintf(comm, 24, "osnoise/%d", cpu); 1434 1464 } 1465 + #else 1466 + snprintf(comm, 24, "osnoise/%d", cpu); 1467 + #endif 1468 + kthread = kthread_create_on_cpu(main, NULL, cpu, comm); 1469 + 1470 + if (IS_ERR(kthread)) { 1471 + pr_err(BANNER "could not start sampling thread\n"); 1472 + stop_per_cpu_kthreads(); 1473 + return -ENOMEM; 1474 + } 1475 + 1476 + per_cpu(per_cpu_osnoise_var, cpu).kthread = kthread; 1477 + wake_up_process(kthread); 1478 + 1479 + return 0; 1435 1480 } 1436 1481 1437 1482 /* ··· 1488 1443 static int start_per_cpu_kthreads(struct trace_array *tr) 1489 1444 { 1490 1445 struct cpumask *current_mask = &save_cpumask; 1491 - struct task_struct *kthread; 1492 - char comm[24]; 1493 - void *main = osnoise_main; 1446 + int retval; 1494 1447 int cpu; 1495 1448 1496 1449 get_online_cpus(); ··· 1500 1457 * And the CPU is online. 1501 1458 */ 1502 1459 cpumask_and(current_mask, cpu_online_mask, current_mask); 1503 - put_online_cpus(); 1504 1460 1505 - for_each_online_cpu(cpu) 1461 + for_each_possible_cpu(cpu) 1506 1462 per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; 1507 1463 1508 1464 for_each_cpu(cpu, current_mask) { 1509 - #ifdef CONFIG_TIMERLAT_TRACER 1510 - if (osnoise_data.timerlat_tracer) { 1511 - snprintf(comm, 24, "timerlat/%d", cpu); 1512 - main = timerlat_main; 1513 - } else { 1514 - snprintf(comm, 24, "osnoise/%d", cpu); 1515 - } 1516 - #else 1517 - snprintf(comm, 24, "osnoise/%d", cpu); 1518 - #endif 1519 - kthread = kthread_create_on_cpu(main, NULL, cpu, comm); 1520 - 1521 - if (IS_ERR(kthread)) { 1522 - pr_err(BANNER "could not start sampling thread\n"); 1465 + retval = start_kthread(cpu); 1466 + if (retval) { 1523 1467 stop_per_cpu_kthreads(); 1524 - return -ENOMEM; 1468 + return retval; 1525 1469 } 1526 - 1527 - per_cpu(per_cpu_osnoise_var, cpu).kthread = kthread; 1528 - wake_up_process(kthread); 1529 1470 } 1471 + 1472 + put_online_cpus(); 1530 1473 1531 1474 return 0; 1532 1475 } 1476 + 1477 + #ifdef CONFIG_HOTPLUG_CPU 1478 + static void osnoise_hotplug_workfn(struct work_struct *dummy) 1479 + { 1480 + struct trace_array *tr = osnoise_trace; 1481 + unsigned int cpu = smp_processor_id(); 1482 + 1483 + 1484 + mutex_lock(&trace_types_lock); 1485 + 1486 + if (!osnoise_busy) 1487 + goto out_unlock_trace; 1488 + 1489 + mutex_lock(&interface_lock); 1490 + get_online_cpus(); 1491 + 1492 + if (!cpumask_test_cpu(cpu, &osnoise_cpumask)) 1493 + goto out_unlock; 1494 + 1495 + if (!cpumask_test_cpu(cpu, tr->tracing_cpumask)) 1496 + goto out_unlock; 1497 + 1498 + start_kthread(cpu); 1499 + 1500 + out_unlock: 1501 + put_online_cpus(); 1502 + mutex_unlock(&interface_lock); 1503 + out_unlock_trace: 1504 + mutex_unlock(&trace_types_lock); 1505 + } 1506 + 1507 + static DECLARE_WORK(osnoise_hotplug_work, osnoise_hotplug_workfn); 1508 + 1509 + /* 1510 + * osnoise_cpu_init - CPU hotplug online callback function 1511 + */ 1512 + static int osnoise_cpu_init(unsigned int cpu) 1513 + { 1514 + schedule_work_on(cpu, &osnoise_hotplug_work); 1515 + return 0; 1516 + } 1517 + 1518 + /* 1519 + * osnoise_cpu_die - CPU hotplug offline callback function 1520 + */ 1521 + static int osnoise_cpu_die(unsigned int cpu) 1522 + { 1523 + stop_kthread(cpu); 1524 + return 0; 1525 + } 1526 + 1527 + static void osnoise_init_hotplug_support(void) 1528 + { 1529 + int ret; 1530 + 1531 + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "trace/osnoise:online", 1532 + osnoise_cpu_init, osnoise_cpu_die); 1533 + if (ret < 0) 1534 + pr_warn(BANNER "Error to init cpu hotplug support\n"); 1535 + 1536 + return; 1537 + } 1538 + #else /* CONFIG_HOTPLUG_CPU */ 1539 + static void osnoise_init_hotplug_support(void) 1540 + { 1541 + return 0; 1542 + } 1543 + #endif /* CONFIG_HOTPLUG_CPU */ 1533 1544 1534 1545 /* 1535 1546 * osnoise_cpus_read - Read function for reading the "cpus" file ··· 1680 1583 osnoise_tracer_stop(tr); 1681 1584 1682 1585 mutex_lock(&interface_lock); 1586 + /* 1587 + * osnoise_cpumask is read by CPU hotplug operations. 1588 + */ 1589 + get_online_cpus(); 1590 + 1683 1591 cpumask_copy(&osnoise_cpumask, osnoise_cpumask_new); 1592 + 1593 + put_online_cpus(); 1684 1594 mutex_unlock(&interface_lock); 1685 1595 1686 1596 if (running) ··· 2044 1940 return ret; 2045 1941 } 2046 1942 #endif 1943 + osnoise_init_hotplug_support(); 2047 1944 2048 1945 init_tracefs(); 2049 1946