summaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/hardwall.c
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2011-05-26 18:40:09 +0200
committerChris Metcalf <cmetcalf@tilera.com>2011-05-27 16:39:05 +0200
commitf133ecca9cbb31b5e6e9bda27cbe3034fbf656df (patch)
tree1887377b71ee9fc73d4e1226d1d9776ae5a5d7ad /arch/tile/kernel/hardwall.c
parentMerge tag 'v2.6.39' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds... (diff)
downloadlinux-f133ecca9cbb31b5e6e9bda27cbe3034fbf656df.tar.xz
linux-f133ecca9cbb31b5e6e9bda27cbe3034fbf656df.zip
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>
Diffstat (limited to 'arch/tile/kernel/hardwall.c')
-rw-r--r--arch/tile/kernel/hardwall.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c
index 3bddef710de4..8c41891aab34 100644
--- a/arch/tile/kernel/hardwall.c
+++ b/arch/tile/kernel/hardwall.c
@@ -40,16 +40,25 @@
struct hardwall_info {
struct list_head list; /* "rectangles" list */
struct list_head task_head; /* head of tasks in this hardwall */
+ struct cpumask cpumask; /* cpus in the rectangle */
int ulhc_x; /* upper left hand corner x coord */
int ulhc_y; /* upper left hand corner y coord */
int width; /* rectangle width */
int height; /* rectangle height */
+ int id; /* integer id for this hardwall */
int teardown_in_progress; /* are we tearing this one down? */
};
/* Currently allocated hardwall rectangles */
static LIST_HEAD(rectangles);
+/* /proc/tile/hardwall */
+static struct proc_dir_entry *hardwall_proc_dir;
+
+/* Functions to manage files in /proc/tile/hardwall. */
+static void hardwall_add_proc(struct hardwall_info *rect);
+static void hardwall_remove_proc(struct hardwall_info *rect);
+
/*
* Guard changes to the hardwall data structures.
* This could be finer grained (e.g. one lock for the list of hardwall
@@ -105,6 +114,8 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
r->ulhc_y = cpu_y(ulhc);
r->width = cpu_x(lrhc) - r->ulhc_x + 1;
r->height = cpu_y(lrhc) - r->ulhc_y + 1;
+ cpumask_copy(&r->cpumask, mask);
+ r->id = ulhc; /* The ulhc cpu id can be the hardwall id. */
/* Width and height must be positive */
if (r->width <= 0 || r->height <= 0)
@@ -388,6 +399,9 @@ static struct hardwall_info *hardwall_create(
/* Set up appropriate hardwalling on all affected cpus. */
hardwall_setup(rect);
+ /* Create a /proc/tile/hardwall entry. */
+ hardwall_add_proc(rect);
+
return rect;
}
@@ -645,6 +659,9 @@ static void hardwall_destroy(struct hardwall_info *rect)
/* Restart switch and disable firewall. */
on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1);
+ /* Remove the /proc/tile/hardwall entry. */
+ hardwall_remove_proc(rect);
+
/* Now free the rectangle from the list. */
spin_lock_irqsave(&hardwall_lock, flags);
BUG_ON(!list_empty(&rect->task_head));
@@ -654,35 +671,57 @@ static void hardwall_destroy(struct hardwall_info *rect)
}
-/*
- * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c.
- */
-int proc_tile_hardwall_show(struct seq_file *sf, void *v)
+static int hardwall_proc_show(struct seq_file *sf, void *v)
{
- struct hardwall_info *r;
+ struct hardwall_info *rect = sf->private;
+ char buf[256];
- if (udn_disabled) {
- seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height);
- return 0;
- }
-
- spin_lock_irq(&hardwall_lock);
- list_for_each_entry(r, &rectangles, list) {
- struct task_struct *p;
- seq_printf(sf, "%dx%d %d,%d pids:",
- r->width, r->height, r->ulhc_x, r->ulhc_y);
- list_for_each_entry(p, &r->task_head, thread.hardwall_list) {
- unsigned int cpu = cpumask_first(&p->cpus_allowed);
- unsigned int x = cpu % smp_width;
- unsigned int y = cpu / smp_width;
- seq_printf(sf, " %d@%d,%d", p->pid, x, y);
- }
- seq_printf(sf, "\n");
- }
- spin_unlock_irq(&hardwall_lock);
+ int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask);
+ buf[rc++] = '\n';
+ seq_write(sf, buf, rc);
return 0;
}
+static int hardwall_proc_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, hardwall_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations hardwall_proc_fops = {
+ .open = hardwall_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void hardwall_add_proc(struct hardwall_info *rect)
+{
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%d", rect->id);
+ proc_create_data(buf, 0444, hardwall_proc_dir,
+ &hardwall_proc_fops, rect);
+}
+
+static void hardwall_remove_proc(struct hardwall_info *rect)
+{
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%d", rect->id);
+ remove_proc_entry(buf, hardwall_proc_dir);
+}
+
+int proc_pid_hardwall(struct task_struct *task, char *buffer)
+{
+ struct hardwall_info *rect = task->thread.hardwall;
+ return rect ? sprintf(buffer, "%d\n", rect->id) : 0;
+}
+
+void proc_tile_hardwall_init(struct proc_dir_entry *root)
+{
+ if (!udn_disabled)
+ hardwall_proc_dir = proc_mkdir("hardwall", root);
+}
+
/*
* Character device support via ioctl/close.
@@ -716,6 +755,9 @@ static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b)
return -EINVAL;
return hardwall_deactivate(current);
+ case _HARDWALL_GET_ID:
+ return rect ? rect->id : -EINVAL;
+
default:
return -EINVAL;
}