Commit f133ecca9cbb31b5e6e9bda27cbe3034fbf656df
1 parent
7a0287df3e
Exists in
master
and in
7 other branches
arch/tile: more /proc and /sys file support
This change introduces a few of the less controversial /proc and /proc/sys interfaces for tile, along with sysfs attributes for various things that were originally proposed as /proc/tile files. It also adjusts the "hardwall" proc API. Arnd Bergmann reviewed the initial arch/tile submission, which included a complete set of all the /proc/tile and /proc/sys/tile knobs that we had added in a somewhat ad hoc way during initial development, and provided feedback on where most of them should go. One knob turned out to be similar enough to the existing /proc/sys/debug/exception-trace that it was re-implemented to use that model instead. Another knob was /proc/tile/grid, which reported the "grid" dimensions of a tile chip (e.g. 8x8 processors = 64-core chip). Arnd suggested looking at sysfs for that, so this change moves that information to a pair of sysfs attributes (chip_width and chip_height) in the /sys/devices/system/cpu directory. We also put the "chip_serial" and "chip_revision" information from our old /proc/tile/board file as attributes in /sys/devices/system/cpu. Other information collected via hypervisor APIs is now placed in /sys/hypervisor. We create a /sys/hypervisor/type file (holding the constant string "tilera") to be parallel with the Xen use of /sys/hypervisor/type holding "xen". We create three top-level files, "version" (the hypervisor's own version), "config_version" (the version of the configuration file), and "hvconfig" (the contents of the configuration file). The remaining information from our old /proc/tile/board and /proc/tile/switch files becomes an attribute group appearing under /sys/hypervisor/board/. Finally, after some feedback from Arnd Bergmann for the previous version of this patch, the /proc/tile/hardwall file is split up into two conceptual parts. First, a directory /proc/tile/hardwall/ which contains one file per active hardwall, each file named after the hardwall's ID and holding a cpulist that says which cpus are enclosed by the hardwall. Second, a /proc/PID file "hardwall" that is either empty (for non-hardwall-using processes) or contains the hardwall ID. Finally, this change pushes the /proc/sys/tile/unaligned_fixup/ directory, with knobs controlling the kernel code for handling the fixup of unaligned exceptions. Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Showing 7 changed files with 347 additions and 28 deletions Side-by-side Diff
arch/tile/Kconfig
arch/tile/include/asm/hardwall.h
... | ... | @@ -40,6 +40,10 @@ |
40 | 40 | #define HARDWALL_DEACTIVATE \ |
41 | 41 | _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE) |
42 | 42 | |
43 | +#define _HARDWALL_GET_ID 4 | |
44 | +#define HARDWALL_GET_ID \ | |
45 | + _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID) | |
46 | + | |
43 | 47 | #ifndef __KERNEL__ |
44 | 48 | |
45 | 49 | /* This is the canonical name expected by userspace. */ |
... | ... | @@ -47,9 +51,14 @@ |
47 | 51 | |
48 | 52 | #else |
49 | 53 | |
50 | -/* Hook for /proc/tile/hardwall. */ | |
51 | -struct seq_file; | |
52 | -int proc_tile_hardwall_show(struct seq_file *sf, void *v); | |
54 | +/* /proc hooks for hardwall. */ | |
55 | +struct proc_dir_entry; | |
56 | +#ifdef CONFIG_HARDWALL | |
57 | +void proc_tile_hardwall_init(struct proc_dir_entry *root); | |
58 | +int proc_pid_hardwall(struct task_struct *task, char *buffer); | |
59 | +#else | |
60 | +static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {} | |
61 | +#endif | |
53 | 62 | |
54 | 63 | #endif |
55 | 64 |
arch/tile/kernel/Makefile
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | extra-y := vmlinux.lds head_$(BITS).o |
6 | 6 | obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \ |
7 | 7 | pci-dma.o proc.o process.o ptrace.o reboot.o \ |
8 | - setup.o signal.o single_step.o stack.o sys.o time.o traps.o \ | |
8 | + setup.o signal.o single_step.o stack.o sys.o sysfs.o time.o traps.o \ | |
9 | 9 | intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o |
10 | 10 | |
11 | 11 | obj-$(CONFIG_HARDWALL) += hardwall.o |
arch/tile/kernel/hardwall.c
... | ... | @@ -40,16 +40,25 @@ |
40 | 40 | struct hardwall_info { |
41 | 41 | struct list_head list; /* "rectangles" list */ |
42 | 42 | struct list_head task_head; /* head of tasks in this hardwall */ |
43 | + struct cpumask cpumask; /* cpus in the rectangle */ | |
43 | 44 | int ulhc_x; /* upper left hand corner x coord */ |
44 | 45 | int ulhc_y; /* upper left hand corner y coord */ |
45 | 46 | int width; /* rectangle width */ |
46 | 47 | int height; /* rectangle height */ |
48 | + int id; /* integer id for this hardwall */ | |
47 | 49 | int teardown_in_progress; /* are we tearing this one down? */ |
48 | 50 | }; |
49 | 51 | |
50 | 52 | /* Currently allocated hardwall rectangles */ |
51 | 53 | static LIST_HEAD(rectangles); |
52 | 54 | |
55 | +/* /proc/tile/hardwall */ | |
56 | +static struct proc_dir_entry *hardwall_proc_dir; | |
57 | + | |
58 | +/* Functions to manage files in /proc/tile/hardwall. */ | |
59 | +static void hardwall_add_proc(struct hardwall_info *rect); | |
60 | +static void hardwall_remove_proc(struct hardwall_info *rect); | |
61 | + | |
53 | 62 | /* |
54 | 63 | * Guard changes to the hardwall data structures. |
55 | 64 | * This could be finer grained (e.g. one lock for the list of hardwall |
... | ... | @@ -105,6 +114,8 @@ |
105 | 114 | r->ulhc_y = cpu_y(ulhc); |
106 | 115 | r->width = cpu_x(lrhc) - r->ulhc_x + 1; |
107 | 116 | r->height = cpu_y(lrhc) - r->ulhc_y + 1; |
117 | + cpumask_copy(&r->cpumask, mask); | |
118 | + r->id = ulhc; /* The ulhc cpu id can be the hardwall id. */ | |
108 | 119 | |
109 | 120 | /* Width and height must be positive */ |
110 | 121 | if (r->width <= 0 || r->height <= 0) |
... | ... | @@ -388,6 +399,9 @@ |
388 | 399 | /* Set up appropriate hardwalling on all affected cpus. */ |
389 | 400 | hardwall_setup(rect); |
390 | 401 | |
402 | + /* Create a /proc/tile/hardwall entry. */ | |
403 | + hardwall_add_proc(rect); | |
404 | + | |
391 | 405 | return rect; |
392 | 406 | } |
393 | 407 | |
... | ... | @@ -645,6 +659,9 @@ |
645 | 659 | /* Restart switch and disable firewall. */ |
646 | 660 | on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1); |
647 | 661 | |
662 | + /* Remove the /proc/tile/hardwall entry. */ | |
663 | + hardwall_remove_proc(rect); | |
664 | + | |
648 | 665 | /* Now free the rectangle from the list. */ |
649 | 666 | spin_lock_irqsave(&hardwall_lock, flags); |
650 | 667 | BUG_ON(!list_empty(&rect->task_head)); |
651 | 668 | |
652 | 669 | |
653 | 670 | |
654 | 671 | |
... | ... | @@ -654,36 +671,58 @@ |
654 | 671 | } |
655 | 672 | |
656 | 673 | |
657 | -/* | |
658 | - * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c. | |
659 | - */ | |
660 | -int proc_tile_hardwall_show(struct seq_file *sf, void *v) | |
674 | +static int hardwall_proc_show(struct seq_file *sf, void *v) | |
661 | 675 | { |
662 | - struct hardwall_info *r; | |
676 | + struct hardwall_info *rect = sf->private; | |
677 | + char buf[256]; | |
663 | 678 | |
664 | - if (udn_disabled) { | |
665 | - seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height); | |
666 | - return 0; | |
667 | - } | |
668 | - | |
669 | - spin_lock_irq(&hardwall_lock); | |
670 | - list_for_each_entry(r, &rectangles, list) { | |
671 | - struct task_struct *p; | |
672 | - seq_printf(sf, "%dx%d %d,%d pids:", | |
673 | - r->width, r->height, r->ulhc_x, r->ulhc_y); | |
674 | - list_for_each_entry(p, &r->task_head, thread.hardwall_list) { | |
675 | - unsigned int cpu = cpumask_first(&p->cpus_allowed); | |
676 | - unsigned int x = cpu % smp_width; | |
677 | - unsigned int y = cpu / smp_width; | |
678 | - seq_printf(sf, " %d@%d,%d", p->pid, x, y); | |
679 | - } | |
680 | - seq_printf(sf, "\n"); | |
681 | - } | |
682 | - spin_unlock_irq(&hardwall_lock); | |
679 | + int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask); | |
680 | + buf[rc++] = '\n'; | |
681 | + seq_write(sf, buf, rc); | |
683 | 682 | return 0; |
684 | 683 | } |
685 | 684 | |
685 | +static int hardwall_proc_open(struct inode *inode, | |
686 | + struct file *file) | |
687 | +{ | |
688 | + return single_open(file, hardwall_proc_show, PDE(inode)->data); | |
689 | +} | |
686 | 690 | |
691 | +static const struct file_operations hardwall_proc_fops = { | |
692 | + .open = hardwall_proc_open, | |
693 | + .read = seq_read, | |
694 | + .llseek = seq_lseek, | |
695 | + .release = single_release, | |
696 | +}; | |
697 | + | |
698 | +static void hardwall_add_proc(struct hardwall_info *rect) | |
699 | +{ | |
700 | + char buf[64]; | |
701 | + snprintf(buf, sizeof(buf), "%d", rect->id); | |
702 | + proc_create_data(buf, 0444, hardwall_proc_dir, | |
703 | + &hardwall_proc_fops, rect); | |
704 | +} | |
705 | + | |
706 | +static void hardwall_remove_proc(struct hardwall_info *rect) | |
707 | +{ | |
708 | + char buf[64]; | |
709 | + snprintf(buf, sizeof(buf), "%d", rect->id); | |
710 | + remove_proc_entry(buf, hardwall_proc_dir); | |
711 | +} | |
712 | + | |
713 | +int proc_pid_hardwall(struct task_struct *task, char *buffer) | |
714 | +{ | |
715 | + struct hardwall_info *rect = task->thread.hardwall; | |
716 | + return rect ? sprintf(buffer, "%d\n", rect->id) : 0; | |
717 | +} | |
718 | + | |
719 | +void proc_tile_hardwall_init(struct proc_dir_entry *root) | |
720 | +{ | |
721 | + if (!udn_disabled) | |
722 | + hardwall_proc_dir = proc_mkdir("hardwall", root); | |
723 | +} | |
724 | + | |
725 | + | |
687 | 726 | /* |
688 | 727 | * Character device support via ioctl/close. |
689 | 728 | */ |
... | ... | @@ -715,6 +754,9 @@ |
715 | 754 | if (current->thread.hardwall != rect) |
716 | 755 | return -EINVAL; |
717 | 756 | return hardwall_deactivate(current); |
757 | + | |
758 | + case _HARDWALL_GET_ID: | |
759 | + return rect ? rect->id : -EINVAL; | |
718 | 760 | |
719 | 761 | default: |
720 | 762 | return -EINVAL; |
arch/tile/kernel/proc.c
... | ... | @@ -27,6 +27,7 @@ |
27 | 27 | #include <asm/processor.h> |
28 | 28 | #include <asm/sections.h> |
29 | 29 | #include <asm/homecache.h> |
30 | +#include <asm/hardwall.h> | |
30 | 31 | #include <arch/chip.h> |
31 | 32 | |
32 | 33 | |
... | ... | @@ -88,4 +89,76 @@ |
88 | 89 | .stop = c_stop, |
89 | 90 | .show = show_cpuinfo, |
90 | 91 | }; |
92 | + | |
93 | +/* | |
94 | + * Support /proc/tile directory | |
95 | + */ | |
96 | + | |
97 | +static int __init proc_tile_init(void) | |
98 | +{ | |
99 | + struct proc_dir_entry *root = proc_mkdir("tile", NULL); | |
100 | + if (root == NULL) | |
101 | + return 0; | |
102 | + | |
103 | + proc_tile_hardwall_init(root); | |
104 | + | |
105 | + return 0; | |
106 | +} | |
107 | + | |
108 | +arch_initcall(proc_tile_init); | |
109 | + | |
110 | +/* | |
111 | + * Support /proc/sys/tile directory | |
112 | + */ | |
113 | + | |
114 | +#ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ | |
115 | +static ctl_table unaligned_subtable[] = { | |
116 | + { | |
117 | + .procname = "enabled", | |
118 | + .data = &unaligned_fixup, | |
119 | + .maxlen = sizeof(int), | |
120 | + .mode = 0644, | |
121 | + .proc_handler = &proc_dointvec | |
122 | + }, | |
123 | + { | |
124 | + .procname = "printk", | |
125 | + .data = &unaligned_printk, | |
126 | + .maxlen = sizeof(int), | |
127 | + .mode = 0644, | |
128 | + .proc_handler = &proc_dointvec | |
129 | + }, | |
130 | + { | |
131 | + .procname = "count", | |
132 | + .data = &unaligned_fixup_count, | |
133 | + .maxlen = sizeof(int), | |
134 | + .mode = 0644, | |
135 | + .proc_handler = &proc_dointvec | |
136 | + }, | |
137 | + {} | |
138 | +}; | |
139 | + | |
140 | +static ctl_table unaligned_table[] = { | |
141 | + { | |
142 | + .procname = "unaligned_fixup", | |
143 | + .mode = 0555, | |
144 | + .child = unaligned_subtable | |
145 | + }, | |
146 | + {} | |
147 | +}; | |
148 | +#endif | |
149 | + | |
150 | +static struct ctl_path tile_path[] = { | |
151 | + { .procname = "tile" }, | |
152 | + { } | |
153 | +}; | |
154 | + | |
155 | +static int __init proc_sys_tile_init(void) | |
156 | +{ | |
157 | +#ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ | |
158 | + register_sysctl_paths(tile_path, unaligned_table); | |
159 | +#endif | |
160 | + return 0; | |
161 | +} | |
162 | + | |
163 | +arch_initcall(proc_sys_tile_init); |
arch/tile/kernel/sysfs.c
1 | +/* | |
2 | + * Copyright 2011 Tilera Corporation. All Rights Reserved. | |
3 | + * | |
4 | + * This program is free software; you can redistribute it and/or | |
5 | + * modify it under the terms of the GNU General Public License | |
6 | + * as published by the Free Software Foundation, version 2. | |
7 | + * | |
8 | + * This program is distributed in the hope that it will be useful, but | |
9 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | |
11 | + * NON INFRINGEMENT. See the GNU General Public License for | |
12 | + * more details. | |
13 | + * | |
14 | + * /sys entry support. | |
15 | + */ | |
16 | + | |
17 | +#include <linux/sysdev.h> | |
18 | +#include <linux/cpu.h> | |
19 | +#include <linux/slab.h> | |
20 | +#include <linux/smp.h> | |
21 | +#include <hv/hypervisor.h> | |
22 | + | |
23 | +/* Return a string queried from the hypervisor, truncated to page size. */ | |
24 | +static ssize_t get_hv_confstr(char *page, int query) | |
25 | +{ | |
26 | + ssize_t n = hv_confstr(query, (unsigned long)page, PAGE_SIZE - 1); | |
27 | + n = n < 0 ? 0 : min(n, (ssize_t)PAGE_SIZE - 1) - 1; | |
28 | + if (n) | |
29 | + page[n++] = '\n'; | |
30 | + page[n] = '\0'; | |
31 | + return n; | |
32 | +} | |
33 | + | |
34 | +static ssize_t chip_width_show(struct sysdev_class *dev, | |
35 | + struct sysdev_class_attribute *attr, | |
36 | + char *page) | |
37 | +{ | |
38 | + return sprintf(page, "%u\n", smp_width); | |
39 | +} | |
40 | +static SYSDEV_CLASS_ATTR(chip_width, 0444, chip_width_show, NULL); | |
41 | + | |
42 | +static ssize_t chip_height_show(struct sysdev_class *dev, | |
43 | + struct sysdev_class_attribute *attr, | |
44 | + char *page) | |
45 | +{ | |
46 | + return sprintf(page, "%u\n", smp_height); | |
47 | +} | |
48 | +static SYSDEV_CLASS_ATTR(chip_height, 0444, chip_height_show, NULL); | |
49 | + | |
50 | +static ssize_t chip_serial_show(struct sysdev_class *dev, | |
51 | + struct sysdev_class_attribute *attr, | |
52 | + char *page) | |
53 | +{ | |
54 | + return get_hv_confstr(page, HV_CONFSTR_CHIP_SERIAL_NUM); | |
55 | +} | |
56 | +static SYSDEV_CLASS_ATTR(chip_serial, 0444, chip_serial_show, NULL); | |
57 | + | |
58 | +static ssize_t chip_revision_show(struct sysdev_class *dev, | |
59 | + struct sysdev_class_attribute *attr, | |
60 | + char *page) | |
61 | +{ | |
62 | + return get_hv_confstr(page, HV_CONFSTR_CHIP_REV); | |
63 | +} | |
64 | +static SYSDEV_CLASS_ATTR(chip_revision, 0444, chip_revision_show, NULL); | |
65 | + | |
66 | + | |
67 | +static ssize_t type_show(struct sysdev_class *dev, | |
68 | + struct sysdev_class_attribute *attr, | |
69 | + char *page) | |
70 | +{ | |
71 | + return sprintf(page, "tilera\n"); | |
72 | +} | |
73 | +static SYSDEV_CLASS_ATTR(type, 0444, type_show, NULL); | |
74 | + | |
75 | +#define HV_CONF_ATTR(name, conf) \ | |
76 | + static ssize_t name ## _show(struct sysdev_class *dev, \ | |
77 | + struct sysdev_class_attribute *attr, \ | |
78 | + char *page) \ | |
79 | + { \ | |
80 | + return get_hv_confstr(page, conf); \ | |
81 | + } \ | |
82 | + static SYSDEV_CLASS_ATTR(name, 0444, name ## _show, NULL); | |
83 | + | |
84 | +HV_CONF_ATTR(version, HV_CONFSTR_HV_SW_VER) | |
85 | +HV_CONF_ATTR(config_version, HV_CONFSTR_HV_CONFIG_VER) | |
86 | + | |
87 | +HV_CONF_ATTR(board_part, HV_CONFSTR_BOARD_PART_NUM) | |
88 | +HV_CONF_ATTR(board_serial, HV_CONFSTR_BOARD_SERIAL_NUM) | |
89 | +HV_CONF_ATTR(board_revision, HV_CONFSTR_BOARD_REV) | |
90 | +HV_CONF_ATTR(board_description, HV_CONFSTR_BOARD_DESC) | |
91 | +HV_CONF_ATTR(mezz_part, HV_CONFSTR_MEZZ_PART_NUM) | |
92 | +HV_CONF_ATTR(mezz_serial, HV_CONFSTR_MEZZ_SERIAL_NUM) | |
93 | +HV_CONF_ATTR(mezz_revision, HV_CONFSTR_MEZZ_REV) | |
94 | +HV_CONF_ATTR(mezz_description, HV_CONFSTR_MEZZ_DESC) | |
95 | +HV_CONF_ATTR(switch_control, HV_CONFSTR_SWITCH_CONTROL) | |
96 | + | |
97 | +static struct attribute *board_attrs[] = { | |
98 | + &attr_board_part.attr, | |
99 | + &attr_board_serial.attr, | |
100 | + &attr_board_revision.attr, | |
101 | + &attr_board_description.attr, | |
102 | + &attr_mezz_part.attr, | |
103 | + &attr_mezz_serial.attr, | |
104 | + &attr_mezz_revision.attr, | |
105 | + &attr_mezz_description.attr, | |
106 | + &attr_switch_control.attr, | |
107 | + NULL | |
108 | +}; | |
109 | + | |
110 | +static struct attribute_group board_attr_group = { | |
111 | + .name = "board", | |
112 | + .attrs = board_attrs, | |
113 | +}; | |
114 | + | |
115 | + | |
116 | +static struct bin_attribute hvconfig_bin; | |
117 | + | |
118 | +static ssize_t | |
119 | +hvconfig_bin_read(struct file *filp, struct kobject *kobj, | |
120 | + struct bin_attribute *bin_attr, | |
121 | + char *buf, loff_t off, size_t count) | |
122 | +{ | |
123 | + static size_t size; | |
124 | + | |
125 | + /* Lazily learn the true size (minus the trailing NUL). */ | |
126 | + if (size == 0) | |
127 | + size = hv_confstr(HV_CONFSTR_HV_CONFIG, 0, 0) - 1; | |
128 | + | |
129 | + /* Check and adjust input parameters. */ | |
130 | + if (off > size) | |
131 | + return -EINVAL; | |
132 | + if (count > size - off) | |
133 | + count = size - off; | |
134 | + | |
135 | + if (count) { | |
136 | + /* Get a copy of the hvc and copy out the relevant portion. */ | |
137 | + char *hvc; | |
138 | + | |
139 | + size = off + count; | |
140 | + hvc = kmalloc(size, GFP_KERNEL); | |
141 | + if (hvc == NULL) | |
142 | + return -ENOMEM; | |
143 | + hv_confstr(HV_CONFSTR_HV_CONFIG, (unsigned long)hvc, size); | |
144 | + memcpy(buf, hvc + off, count); | |
145 | + kfree(hvc); | |
146 | + } | |
147 | + | |
148 | + return count; | |
149 | +} | |
150 | + | |
151 | +static int __init create_sysfs_entries(void) | |
152 | +{ | |
153 | + struct sysdev_class *cls = &cpu_sysdev_class; | |
154 | + int err = 0; | |
155 | + | |
156 | +#define create_cpu_attr(name) \ | |
157 | + if (!err) \ | |
158 | + err = sysfs_create_file(&cls->kset.kobj, &attr_##name.attr); | |
159 | + create_cpu_attr(chip_width); | |
160 | + create_cpu_attr(chip_height); | |
161 | + create_cpu_attr(chip_serial); | |
162 | + create_cpu_attr(chip_revision); | |
163 | + | |
164 | +#define create_hv_attr(name) \ | |
165 | + if (!err) \ | |
166 | + err = sysfs_create_file(hypervisor_kobj, &attr_##name.attr); | |
167 | + create_hv_attr(type); | |
168 | + create_hv_attr(version); | |
169 | + create_hv_attr(config_version); | |
170 | + | |
171 | + if (!err) | |
172 | + err = sysfs_create_group(hypervisor_kobj, &board_attr_group); | |
173 | + | |
174 | + if (!err) { | |
175 | + sysfs_bin_attr_init(&hvconfig_bin); | |
176 | + hvconfig_bin.attr.name = "hvconfig"; | |
177 | + hvconfig_bin.attr.mode = S_IRUGO; | |
178 | + hvconfig_bin.read = hvconfig_bin_read; | |
179 | + hvconfig_bin.size = PAGE_SIZE; | |
180 | + err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin); | |
181 | + } | |
182 | + | |
183 | + return err; | |
184 | +} | |
185 | +subsys_initcall(create_sysfs_entries); |
fs/proc/base.c
... | ... | @@ -83,6 +83,9 @@ |
83 | 83 | #include <linux/pid_namespace.h> |
84 | 84 | #include <linux/fs_struct.h> |
85 | 85 | #include <linux/slab.h> |
86 | +#ifdef CONFIG_HARDWALL | |
87 | +#include <asm/hardwall.h> | |
88 | +#endif | |
86 | 89 | #include "internal.h" |
87 | 90 | |
88 | 91 | /* NOTE: |
... | ... | @@ -2894,6 +2897,9 @@ |
2894 | 2897 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2895 | 2898 | INF("io", S_IRUGO, proc_tgid_io_accounting), |
2896 | 2899 | #endif |
2900 | +#ifdef CONFIG_HARDWALL | |
2901 | + INF("hardwall", S_IRUGO, proc_pid_hardwall), | |
2902 | +#endif | |
2897 | 2903 | }; |
2898 | 2904 | |
2899 | 2905 | static int proc_tgid_base_readdir(struct file * filp, |
... | ... | @@ -3231,6 +3237,9 @@ |
3231 | 3237 | #endif |
3232 | 3238 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
3233 | 3239 | INF("io", S_IRUGO, proc_tid_io_accounting), |
3240 | +#endif | |
3241 | +#ifdef CONFIG_HARDWALL | |
3242 | + INF("hardwall", S_IRUGO, proc_pid_hardwall), | |
3234 | 3243 | #endif |
3235 | 3244 | }; |
3236 | 3245 |