Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f133ecca authored by Chris Metcalf's avatar Chris Metcalf
Browse files

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: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarChris Metcalf <cmetcalf@tilera.com>
parent 7a0287df
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@ config TILE
	select GENERIC_IRQ_PROBE
	select GENERIC_IRQ_PROBE
	select GENERIC_PENDING_IRQ if SMP
	select GENERIC_PENDING_IRQ if SMP
	select GENERIC_IRQ_SHOW
	select GENERIC_IRQ_SHOW
	select SYS_HYPERVISOR


# FIXME: investigate whether we need/want these options.
# FIXME: investigate whether we need/want these options.
#	select HAVE_IOREMAP_PROT
#	select HAVE_IOREMAP_PROT
+12 −3
Original line number Original line Diff line number Diff line
@@ -40,6 +40,10 @@
#define HARDWALL_DEACTIVATE \
#define HARDWALL_DEACTIVATE \
 _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE)
 _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE)


#define _HARDWALL_GET_ID 4
#define HARDWALL_GET_ID \
 _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID)

#ifndef __KERNEL__
#ifndef __KERNEL__


/* This is the canonical name expected by userspace. */
/* This is the canonical name expected by userspace. */
@@ -47,9 +51,14 @@


#else
#else


/* Hook for /proc/tile/hardwall. */
/* /proc hooks for hardwall. */
struct seq_file;
struct proc_dir_entry;
int proc_tile_hardwall_show(struct seq_file *sf, void *v);
#ifdef CONFIG_HARDWALL
void proc_tile_hardwall_init(struct proc_dir_entry *root);
int proc_pid_hardwall(struct task_struct *task, char *buffer);
#else
static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {}
#endif


#endif
#endif


+1 −1
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@
extra-y := vmlinux.lds head_$(BITS).o
extra-y := vmlinux.lds head_$(BITS).o
obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \
obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \
	pci-dma.o proc.o process.o ptrace.o reboot.o \
	pci-dma.o proc.o process.o ptrace.o reboot.o \
	setup.o signal.o single_step.o stack.o sys.o time.o traps.o \
	setup.o signal.o single_step.o stack.o sys.o sysfs.o time.o traps.o \
	intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o
	intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o


obj-$(CONFIG_HARDWALL)		+= hardwall.o
obj-$(CONFIG_HARDWALL)		+= hardwall.o
+66 −24
Original line number Original line Diff line number Diff line
@@ -40,16 +40,25 @@
struct hardwall_info {
struct hardwall_info {
	struct list_head list;             /* "rectangles" list */
	struct list_head list;             /* "rectangles" list */
	struct list_head task_head;        /* head of tasks in this hardwall */
	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_x;                        /* upper left hand corner x coord */
	int ulhc_y;                        /* upper left hand corner y coord */
	int ulhc_y;                        /* upper left hand corner y coord */
	int width;                         /* rectangle width */
	int width;                         /* rectangle width */
	int height;                        /* rectangle height */
	int height;                        /* rectangle height */
	int id;                            /* integer id for this hardwall */
	int teardown_in_progress;          /* are we tearing this one down? */
	int teardown_in_progress;          /* are we tearing this one down? */
};
};


/* Currently allocated hardwall rectangles */
/* Currently allocated hardwall rectangles */
static LIST_HEAD(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.
 * Guard changes to the hardwall data structures.
 * This could be finer grained (e.g. one lock for the list of hardwall
 * 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->ulhc_y = cpu_y(ulhc);
	r->width = cpu_x(lrhc) - r->ulhc_x + 1;
	r->width = cpu_x(lrhc) - r->ulhc_x + 1;
	r->height = cpu_y(lrhc) - r->ulhc_y + 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 */
	/* Width and height must be positive */
	if (r->width <= 0 || r->height <= 0)
	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. */
	/* Set up appropriate hardwalling on all affected cpus. */
	hardwall_setup(rect);
	hardwall_setup(rect);


	/* Create a /proc/tile/hardwall entry. */
	hardwall_add_proc(rect);

	return rect;
	return rect;
}
}


@@ -645,6 +659,9 @@ static void hardwall_destroy(struct hardwall_info *rect)
	/* Restart switch and disable firewall. */
	/* Restart switch and disable firewall. */
	on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1);
	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. */
	/* Now free the rectangle from the list. */
	spin_lock_irqsave(&hardwall_lock, flags);
	spin_lock_irqsave(&hardwall_lock, flags);
	BUG_ON(!list_empty(&rect->task_head));
	BUG_ON(!list_empty(&rect->task_head));
@@ -654,33 +671,55 @@ static void hardwall_destroy(struct hardwall_info *rect)
}
}




/*
static int hardwall_proc_show(struct seq_file *sf, void *v)
 * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c.
 */
int proc_tile_hardwall_show(struct seq_file *sf, void *v)
{
{
	struct hardwall_info *r;
	struct hardwall_info *rect = sf->private;
	char buf[256];


	if (udn_disabled) {
	int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask);
		seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height);
	buf[rc++] = '\n';
	seq_write(sf, buf, rc);
	return 0;
	return 0;
}
}


	spin_lock_irq(&hardwall_lock);
static int hardwall_proc_open(struct inode *inode,
	list_for_each_entry(r, &rectangles, list) {
			      struct file *file)
		struct task_struct *p;
{
		seq_printf(sf, "%dx%d %d,%d pids:",
	return single_open(file, hardwall_proc_show, PDE(inode)->data);
			   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);
static const struct file_operations hardwall_proc_fops = {
			unsigned int x = cpu % smp_width;
	.open		= hardwall_proc_open,
			unsigned int y = cpu / smp_width;
	.read		= seq_read,
			seq_printf(sf, " %d@%d,%d", p->pid, x, y);
	.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);
}
}
		seq_printf(sf, "\n");

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);
}
}
	spin_unlock_irq(&hardwall_lock);

	return 0;
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);
}
}




@@ -716,6 +755,9 @@ static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b)
			return -EINVAL;
			return -EINVAL;
		return hardwall_deactivate(current);
		return hardwall_deactivate(current);


	case _HARDWALL_GET_ID:
		return rect ? rect->id : -EINVAL;

	default:
	default:
		return -EINVAL;
		return -EINVAL;
	}
	}
+73 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#include <asm/processor.h>
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/sections.h>
#include <asm/homecache.h>
#include <asm/homecache.h>
#include <asm/hardwall.h>
#include <arch/chip.h>
#include <arch/chip.h>




@@ -88,3 +89,75 @@ const struct seq_operations cpuinfo_op = {
	.stop	= c_stop,
	.stop	= c_stop,
	.show	= show_cpuinfo,
	.show	= show_cpuinfo,
};
};

/*
 * Support /proc/tile directory
 */

static int __init proc_tile_init(void)
{
	struct proc_dir_entry *root = proc_mkdir("tile", NULL);
	if (root == NULL)
		return 0;

	proc_tile_hardwall_init(root);

	return 0;
}

arch_initcall(proc_tile_init);

/*
 * Support /proc/sys/tile directory
 */

#ifndef __tilegx__  /* FIXME: GX: no support for unaligned access yet */
static ctl_table unaligned_subtable[] = {
	{
		.procname	= "enabled",
		.data		= &unaligned_fixup,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= &proc_dointvec
	},
	{
		.procname	= "printk",
		.data		= &unaligned_printk,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= &proc_dointvec
	},
	{
		.procname	= "count",
		.data		= &unaligned_fixup_count,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= &proc_dointvec
	},
	{}
};

static ctl_table unaligned_table[] = {
	{
		.procname	= "unaligned_fixup",
		.mode		= 0555,
		.child		= unaligned_subtable
	},
	{}
};
#endif

static struct ctl_path tile_path[] = {
	{ .procname = "tile" },
	{ }
};

static int __init proc_sys_tile_init(void)
{
#ifndef __tilegx__  /* FIXME: GX: no support for unaligned access yet */
	register_sysctl_paths(tile_path, unaligned_table);
#endif
	return 0;
}

arch_initcall(proc_sys_tile_init);
Loading