History

sched,debug: Convert sysctl sched_domains to debugfs

Stop polluting sysctl, move to debugfs for SCHED_DEBUG stuff.

Peter Zijlstra committed 5 years ago

Commit 3b87f131 parent 9af04403 files · +59 −211Browse files

Unified · Split

3 files
  1. kernel/sched/debug.c +55 −199
  2. kernel/sched/sched.h +3 −7
  3. kernel/sched/topology.c +1 −5
kernel/sched/debug.c+55−199
@@ -299,6 +299,10 @@ static __init int sched_init_debug(void) · 298 unmodified lines
299299 debugfs_create_file("tunable_scaling", 0644, debugfs_sched, NULL, &sched_scaling_fops);
300300 debugfs_create_u32("migration_cost_ns", 0644, debugfs_sched, &sysctl_sched_migration_cost);
301301 debugfs_create_u32("nr_migrate", 0644, debugfs_sched, &sysctl_sched_nr_migrate);
302+
303+ mutex_lock(&sched_domains_mutex);
304+ update_sched_domain_debugfs();
305+ mutex_unlock(&sched_domains_mutex);
302306 #endif
303307
304308 #ifdef CONFIG_NUMA_BALANCING
@@ -316,229 +320,88 @@ late_initcall(sched_init_debug); · 11 unmodified lines
316320
317321 #ifdef CONFIG_SMP
318322
319−#ifdef CONFIG_SYSCTL
320−
321−static struct ctl_table sd_ctl_dir[] = {
322− {
323− .procname = "sched_domain",
324− .mode = 0555,
325− },
326− {}
327−};
328−
329−static struct ctl_table sd_ctl_root[] = {
330− {
331− .procname = "kernel",
332− .mode = 0555,
333− .child = sd_ctl_dir,
334− },
335− {}
336−};
337−
338−static struct ctl_table *sd_alloc_ctl_entry(int n)
339−{
340− struct ctl_table *entry =
341− kcalloc(n, sizeof(struct ctl_table), GFP_KERNEL);
342−
343− return entry;
344−}
345−
346−static void sd_free_ctl_entry(struct ctl_table **tablep)
347−{
348− struct ctl_table *entry;
349−
350− /*
351− * In the intermediate directories, both the child directory and
352− * procname are dynamically allocated and could fail but the mode
353− * will always be set. In the lowest directory the names are
354− * static strings and all have proc handlers.
355− */
356− for (entry = *tablep; entry->mode; entry++) {
357− if (entry->child)
358− sd_free_ctl_entry(&entry->child);
359− if (entry->proc_handler == NULL)
360− kfree(entry->procname);
361− }
362−
363− kfree(*tablep);
364− *tablep = NULL;
365−}
366−
367−static void
368−set_table_entry(struct ctl_table *entry,
369− const char *procname, void *data, int maxlen,
370− umode_t mode, proc_handler *proc_handler)
371−{
372− entry->procname = procname;
373− entry->data = data;
374− entry->maxlen = maxlen;
375− entry->mode = mode;
376− entry->proc_handler = proc_handler;
377−}
323+static cpumask_var_t sd_sysctl_cpus;
324+static struct dentry *sd_dentry;
378325
379−static int sd_ctl_doflags(struct ctl_table *table, int write,
380− void *buffer, size_t *lenp, loff_t *ppos)
326+static int sd_flags_show(struct seq_file *m, void *v)
381327 {
382− unsigned long flags = *(unsigned long *)table->data;
383− size_t data_size = 0;
384− size_t len = 0;
385− char *tmp, *buf;
328+ unsigned long flags = *(unsigned int *)m->private;
386329 int idx;
387330
388− if (write)
389− return 0;
390−
391− for_each_set_bit(idx, &flags, __SD_FLAG_CNT) {
392− char *name = sd_flag_debug[idx].name;
393−
394− /* Name plus whitespace */
395− data_size += strlen(name) + 1;
396− }
397−
398− if (*ppos > data_size) {
399− *lenp = 0;
400− return 0;
401− }
402−
403− buf = kcalloc(data_size + 1, sizeof(*buf), GFP_KERNEL);
404− if (!buf)
405− return -ENOMEM;
406−
407331 for_each_set_bit(idx, &flags, __SD_FLAG_CNT) {
408− char *name = sd_flag_debug[idx].name;
409−
410− len += snprintf(buf + len, strlen(name) + 2, "%s ", name);
411− }
412−
413− tmp = buf + *ppos;
414− len -= *ppos;
415−
416− if (len > *lenp)
417− len = *lenp;
418− if (len)
419− memcpy(buffer, tmp, len);
420− if (len < *lenp) {
421− ((char *)buffer)[len] = '\n';
422− len++;
332+ seq_puts(m, sd_flag_debug[idx].name);
333+ seq_puts(m, " ");
423334 }
424−
425− *lenp = len;
426− *ppos += len;
427−
428− kfree(buf);
335+ seq_puts(m, "\n");
429336
430337 return 0;
431338 }
432339
433−static struct ctl_table *
434−sd_alloc_ctl_domain_table(struct sched_domain *sd)
435−{
436− struct ctl_table *table = sd_alloc_ctl_entry(9);
437−
438− if (table == NULL)
439− return NULL;
440−
441− set_table_entry(&table[0], "min_interval", &sd->min_interval, sizeof(long), 0644, proc_doulongvec_minmax);
442− set_table_entry(&table[1], "max_interval", &sd->max_interval, sizeof(long), 0644, proc_doulongvec_minmax);
443− set_table_entry(&table[2], "busy_factor", &sd->busy_factor, sizeof(int), 0644, proc_dointvec_minmax);
444− set_table_entry(&table[3], "imbalance_pct", &sd->imbalance_pct, sizeof(int), 0644, proc_dointvec_minmax);
445− set_table_entry(&table[4], "cache_nice_tries", &sd->cache_nice_tries, sizeof(int), 0644, proc_dointvec_minmax);
446− set_table_entry(&table[5], "flags", &sd->flags, sizeof(int), 0444, sd_ctl_doflags);
447− set_table_entry(&table[6], "max_newidle_lb_cost", &sd->max_newidle_lb_cost, sizeof(long), 0644, proc_doulongvec_minmax);
448− set_table_entry(&table[7], "name", sd->name, CORENAME_MAX_SIZE, 0444, proc_dostring);
449− /* &table[8] is terminator */
450−
451− return table;
452−}
453−
454−static struct ctl_table *sd_alloc_ctl_cpu_table(int cpu)
340+static int sd_flags_open(struct inode *inode, struct file *file)
455341 {
456− struct ctl_table *entry, *table;
457− struct sched_domain *sd;
458− int domain_num = 0, i;
459− char buf[32];
460−
461− for_each_domain(cpu, sd)
462− domain_num++;
463− entry = table = sd_alloc_ctl_entry(domain_num + 1);
464− if (table == NULL)
465− return NULL;
466−
467− i = 0;
468− for_each_domain(cpu, sd) {
469− snprintf(buf, 32, "domain%d", i);
470− entry->procname = kstrdup(buf, GFP_KERNEL);
471− entry->mode = 0555;
472− entry->child = sd_alloc_ctl_domain_table(sd);
473− entry++;
474− i++;
475− }
476− return table;
342+ return single_open(file, sd_flags_show, inode->i_private);
477343 }
478344
479−static cpumask_var_t sd_sysctl_cpus;
480−static struct ctl_table_header *sd_sysctl_header;
345+static const struct file_operations sd_flags_fops = {
346+ .open = sd_flags_open,
347+ .read = seq_read,
348+ .llseek = seq_lseek,
349+ .release = single_release,
350+};
481351
482−void register_sched_domain_sysctl(void)
352+static void register_sd(struct sched_domain *sd, struct dentry *parent)
483353 {
484− static struct ctl_table *cpu_entries;
485− static struct ctl_table **cpu_idx;
486− static bool init_done = false;
487− char buf[32];
488− int i;
354+#define SDM(type, mode, member) \
355+ debugfs_create_##type(#member, mode, parent, &sd->member)
489356
490− if (!cpu_entries) {
491− cpu_entries = sd_alloc_ctl_entry(num_possible_cpus() + 1);
492− if (!cpu_entries)
493− return;
494−
495− WARN_ON(sd_ctl_dir[0].child);
496− sd_ctl_dir[0].child = cpu_entries;
497− }
357+ SDM(ulong, 0644, min_interval);
358+ SDM(ulong, 0644, max_interval);
359+ SDM(u64, 0644, max_newidle_lb_cost);
360+ SDM(u32, 0644, busy_factor);
361+ SDM(u32, 0644, imbalance_pct);
362+ SDM(u32, 0644, cache_nice_tries);
363+ SDM(str, 0444, name);
498364
499− if (!cpu_idx) {
500− struct ctl_table *e = cpu_entries;
365+#undef SDM
501366
502− cpu_idx = kcalloc(nr_cpu_ids, sizeof(struct ctl_table*), GFP_KERNEL);
503− if (!cpu_idx)
504− return;
367+ debugfs_create_file("flags", 0444, parent, &sd->flags, &sd_flags_fops);
368+}
505369
506− /* deal with sparse possible map */
507− for_each_possible_cpu(i) {
508− cpu_idx[i] = e;
509− e++;
510− }
511− }
370+void update_sched_domain_debugfs(void)
371+{
372+ int cpu, i;
512373
513374 if (!cpumask_available(sd_sysctl_cpus)) {
514375 if (!alloc_cpumask_var(&sd_sysctl_cpus, GFP_KERNEL))
515376 return;
516− }
517−
518− if (!init_done) {
519− init_done = true;
520− /* init to possible to not have holes in @cpu_entries */
521377 cpumask_copy(sd_sysctl_cpus, cpu_possible_mask);
522378 }
523379
524− for_each_cpu(i, sd_sysctl_cpus) {
525− struct ctl_table *e = cpu_idx[i];
380+ if (!sd_dentry)
381+ sd_dentry = debugfs_create_dir("domains", debugfs_sched);
382+
383+ for_each_cpu(cpu, sd_sysctl_cpus) {
384+ struct sched_domain *sd;
385+ struct dentry *d_cpu;
386+ char buf[32];
387+
388+ snprintf(buf, sizeof(buf), "cpu%d", cpu);
389+ debugfs_remove(debugfs_lookup(buf, sd_dentry));
390+ d_cpu = debugfs_create_dir(buf, sd_dentry);
526391
527− if (e->child)
528− sd_free_ctl_entry(&e->child);
392+ i = 0;
393+ for_each_domain(cpu, sd) {
394+ struct dentry *d_sd;
529395
530− if (!e->procname) {
531− snprintf(buf, 32, "cpu%d", i);
532− e->procname = kstrdup(buf, GFP_KERNEL);
396+ snprintf(buf, sizeof(buf), "domain%d", i);
397+ d_sd = debugfs_create_dir(buf, d_cpu);
398+
399+ register_sd(sd, d_sd);
400+ i++;
533401 }
534− e->mode = 0555;
535− e->child = sd_alloc_ctl_cpu_table(i);
536402
537− __cpumask_clear_cpu(i, sd_sysctl_cpus);
403+ __cpumask_clear_cpu(cpu, sd_sysctl_cpus);
538404 }
539−
540− WARN_ON(sd_sysctl_header);
541− sd_sysctl_header = register_sysctl_table(sd_ctl_root);
542405 }
543406
544407 void dirty_sched_domain_sysctl(int cpu)
@@ -547,13 +410,6 @@ void dirty_sched_domain_sysctl(int cpu) · 2 unmodified lines
547410 __cpumask_set_cpu(cpu, sd_sysctl_cpus);
548411 }
549412
550−/* may be called multiple times per register */
551−void unregister_sched_domain_sysctl(void)
552−{
553− unregister_sysctl_table(sd_sysctl_header);
554− sd_sysctl_header = NULL;
555−}
556−#endif /* CONFIG_SYSCTL */
557413 #endif /* CONFIG_SMP */
558414
559415 #ifdef CONFIG_FAIR_GROUP_SCHED
kernel/sched/sched.h+3−7
@@ -1552,20 +1552,16 @@ static inline unsigned int group_first_cpu(struct sched_group *group) · 1551 unmodified lines
15521552
15531553 extern int group_balance_cpu(struct sched_group *sg);
15541554
1555−#if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL)
1556−void register_sched_domain_sysctl(void);
1555+#ifdef CONFIG_SCHED_DEBUG
1556+void update_sched_domain_debugfs(void);
15571557 void dirty_sched_domain_sysctl(int cpu);
1558−void unregister_sched_domain_sysctl(void);
15591558 #else
1560−static inline void register_sched_domain_sysctl(void)
1559+static inline void update_sched_domain_debugfs(void)
15611560 {
15621561 }
15631562 static inline void dirty_sched_domain_sysctl(int cpu)
15641563 {
15651564 }
1566−static inline void unregister_sched_domain_sysctl(void)
1567−{
1568−}
15691565 #endif
15701566
15711567 extern int sched_update_scaling(void);
kernel/sched/topology.c+1−5
@@ -2223,7 +2223,6 @@ int sched_init_domains(const struct cpumask *cpu_map) · 2222 unmodified lines
22232223 doms_cur = &fallback_doms;
22242224 cpumask_and(doms_cur[0], cpu_map, housekeeping_cpumask(HK_FLAG_DOMAIN));
22252225 err = build_sched_domains(doms_cur[0], NULL);
2226− register_sched_domain_sysctl();
22272226
22282227 return err;
22292228 }
@@ -2298,9 +2297,6 @@ void partition_sched_domains_locked(int ndoms_new, cpumask_var_t doms_new[], · 68 unmodified lines
22982297
22992298 lockdep_assert_held(&sched_domains_mutex);
23002299
2301− /* Always unregister in case we don't destroy any domains: */
2302− unregister_sched_domain_sysctl();
2303−
23042300 /* Let the architecture update CPU core mappings: */
23052301 new_topology = arch_update_cpu_topology();
23062302
@@ -2389,7 +2385,7 @@ match3: · 82 unmodified lines
23892385 dattr_cur = dattr_new;
23902386 ndoms_cur = ndoms_new;
23912387
2392− register_sched_domain_sysctl();
2388+ update_sched_domain_debugfs();
23932389 }
23942390
23952391 /*

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t