From 4ab0d47d0ab311eb181532c1ecb6d02905685071 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Tue, 24 Feb 2009 17:35:12 -0800 Subject: gpu/drm, x86, PAT: io_mapping_create_wc and resource_size_t io_mapping_create_wc should take a resource_size_t parameter in place of unsigned long. With unsigned long, there will be no way to map greater than 4GB address in i386/32 bit. On x86, greater than 4GB addresses cannot be mapped on i386 without PAE. Return error for such a case. Patch also adds a structure for io_mapping, that saves the base, size and type on HAVE_ATOMIC_IOMAP archs, that can be used to verify the offset on io_mapping_map calls. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Cc: Dave Airlie Cc: Jesse Barnes Cc: Eric Anholt Cc: Keith Packard Signed-off-by: Ingo Molnar --- include/linux/io-mapping.h | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 82df31726a54..cbc2f0cd631b 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -30,11 +30,14 @@ * See Documentation/io_mapping.txt */ -/* this struct isn't actually defined anywhere */ -struct io_mapping; - #ifdef CONFIG_HAVE_ATOMIC_IOMAP +struct io_mapping { + resource_size_t base; + unsigned long size; + pgprot_t prot; +}; + /* * For small address space machines, mapping large objects * into the kernel virtual space isn't practical. Where @@ -43,23 +46,40 @@ struct io_mapping; */ static inline struct io_mapping * -io_mapping_create_wc(unsigned long base, unsigned long size) +io_mapping_create_wc(resource_size_t base, unsigned long size) { - return (struct io_mapping *) base; + struct io_mapping *iomap; + + if (!is_io_mapping_possible(base, size)) + return NULL; + + iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); + if (!iomap) + return NULL; + + iomap->base = base; + iomap->size = size; + iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL)); + return iomap; } static inline void io_mapping_free(struct io_mapping *mapping) { + kfree(mapping); } /* Atomic map/unmap */ static inline void * io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) { - offset += (unsigned long) mapping; - return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, - __pgprot(__PAGE_KERNEL_WC)); + resource_size_t phys_addr; + unsigned long pfn; + + BUG_ON(offset >= mapping->size); + phys_addr = mapping->base + offset; + pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); + return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot); } static inline void @@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr) static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) { - offset += (unsigned long) mapping; - return ioremap_wc(offset, PAGE_SIZE); + BUG_ON(offset >= mapping->size); + resource_size_t phys_addr = mapping->base + offset; + return ioremap_wc(phys_addr, PAGE_SIZE); } static inline void @@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr) #else +/* this struct isn't actually defined anywhere */ +struct io_mapping; + /* Create the io_mapping object*/ static inline struct io_mapping * -io_mapping_create_wc(unsigned long base, unsigned long size) +io_mapping_create_wc(resource_size_t base, unsigned long size) { return (struct io_mapping *) ioremap_wc(base, size); } -- cgit v1.2.2 From 5170836679185357dc1b7660bad13287b39e1e33 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 27 Feb 2009 14:03:03 -0800 Subject: Fix recursive lock in free_uid()/free_user_ns() free_uid() and free_user_ns() are corecursive when CONFIG_USER_SCHED=n, but free_user_ns() is called from free_uid() by way of uid_hash_remove(), which requires uidhash_lock to be held. free_user_ns() then calls free_uid() to complete the destruction. Fix this by deferring the destruction of the user_namespace. Signed-off-by: David Howells Acked-by: Serge Hallyn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/user_namespace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 315bcd375224..cc4f45361dbb 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -13,6 +13,7 @@ struct user_namespace { struct kref kref; struct hlist_head uidhash_table[UIDHASH_SZ]; struct user_struct *creator; + struct work_struct destroyer; }; extern struct user_namespace init_user_ns; -- cgit v1.2.2 From eb594e45f6979cd10b18d87f7b3f02119e00a108 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 27 Feb 2009 17:36:06 -0500 Subject: tracing: move trace point formats to files in include/trace directory Impact: clean up To further facilitate the ease of adding trace points for developers, this patch creates include/trace/trace_events.h and include/trace/trace_event_types.h. The former file will hold the trace/.h files and the latter will hold the trace/_event_types.h files. To create new tracepoints and to have them automatically appear in the event tracer, a developer makes the trace/.h file which includes and the trace/_event_types.h file. The trace/_event_types.h file will hold the TRACE_FORMAT macros. Then add the trace/.h file to trace/trace_events.h, and add the trace/_event_types.h to the trace_event_types.h file. No need to modify files elsewhere. Signed-off-by: Steven Rostedt --- include/trace/trace_event_types.h | 4 ++++ include/trace/trace_events.h | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 include/trace/trace_event_types.h create mode 100644 include/trace/trace_events.h (limited to 'include') diff --git a/include/trace/trace_event_types.h b/include/trace/trace_event_types.h new file mode 100644 index 000000000000..33c8ed5ccb6c --- /dev/null +++ b/include/trace/trace_event_types.h @@ -0,0 +1,4 @@ +/* trace/_event_types.h here */ + +#include +#include diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h new file mode 100644 index 000000000000..ea2ef2051762 --- /dev/null +++ b/include/trace/trace_events.h @@ -0,0 +1,4 @@ +/* trace/.h here */ + +#include +#include -- cgit v1.2.2 From 0ec2ef1505b3e1f54b07bf64f184c92859c3e13f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 27 Feb 2009 23:41:43 -0500 Subject: tracing: add subsystem irq for irq events Add the TRACE_SYSTEM irq for the irq events. Signed-off-by: Steven Rostedt --- include/trace/irq_event_types.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h index 5d0919fdd2d4..47a2be1b2d7d 100644 --- a/include/trace/irq_event_types.h +++ b/include/trace/irq_event_types.h @@ -5,6 +5,9 @@ # error Unless you know what you are doing. #endif +#undef TRACE_SYSTEM +#define TRACE_SYSTEM irq + TRACE_FORMAT(irq_handler_entry, TPPROTO(int irq, struct irqaction *action), TPARGS(irq, action), @@ -15,3 +18,5 @@ TRACE_FORMAT(irq_handler_exit, TPARGS(irq, action, ret), TPFMT("irq=%d handler=%s return=%s", irq, action->name, ret ? "handled" : "unhandled")); + +#undef TRACE_SYSTEM -- cgit v1.2.2 From 3d7ba938da8481b4f7f9ed3d943dbae49389b284 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 27 Feb 2009 23:45:52 -0500 Subject: tracing: add subsystem sched for sched events Add the TRACE_SYSTEM sched for the sched events. Signed-off-by: Steven Rostedt --- include/trace/sched_event_types.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h index a3d3d66a51c8..2ada206565a3 100644 --- a/include/trace/sched_event_types.h +++ b/include/trace/sched_event_types.h @@ -5,6 +5,9 @@ # error Unless you know what you are doing. #endif +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sched + TRACE_FORMAT(sched_kthread_stop, TPPROTO(struct task_struct *t), TPARGS(t), @@ -70,3 +73,5 @@ TRACE_FORMAT(sched_signal_send, TPPROTO(int sig, struct task_struct *p), TPARGS(sig, p), TPFMT("sig: %d task %s:%d", sig, p->comm, p->pid)); + +#undef TRACE_SYSTEM -- cgit v1.2.2 From 629928041c53771f9902753d50fef6b35f36d33d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sat, 28 Feb 2009 02:47:59 -0500 Subject: tracing: create the C style tracing for the sched subsystem This patch utilizes the TRACE_EVENT_FORMAT macro to enable the C style faster tracing for the sched subsystem trace points. Signed-off-by: Steven Rostedt --- include/linux/tracepoint.h | 3 + include/trace/sched_event_types.h | 119 ++++++++++++++++++++++++++++++-------- 2 files changed, 97 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 62d13391a240..152b2f03fb86 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -157,4 +157,7 @@ static inline void tracepoint_synchronize_unregister(void) #define TRACE_FORMAT(name, proto, args, fmt) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) +#define TRACE_EVENT_FORMAT(name, proto, args, fmt, struct, tpfmt) \ + TRACE_FORMAT(name, PARAMS(proto), PARAMS(args), PARAMS(fmt)) + #endif diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h index 2ada206565a3..ba059c10b58a 100644 --- a/include/trace/sched_event_types.h +++ b/include/trace/sched_event_types.h @@ -1,6 +1,6 @@ /* use instead */ -#ifndef TRACE_FORMAT +#ifndef TRACE_EVENT_FORMAT # error Do not include this file directly. # error Unless you know what you are doing. #endif @@ -8,70 +8,139 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM sched -TRACE_FORMAT(sched_kthread_stop, +TRACE_EVENT_FORMAT(sched_kthread_stop, TPPROTO(struct task_struct *t), TPARGS(t), - TPFMT("task %s:%d", t->comm, t->pid)); + TPFMT("task %s:%d", t->comm, t->pid), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, t->pid) + ), + TPRAWFMT("task %d") + ); -TRACE_FORMAT(sched_kthread_stop_ret, +TRACE_EVENT_FORMAT(sched_kthread_stop_ret, TPPROTO(int ret), TPARGS(ret), - TPFMT("ret=%d", ret)); + TPFMT("ret=%d", ret), + TRACE_STRUCT( + TRACE_FIELD(int, ret, ret) + ), + TPRAWFMT("ret=%d") + ); -TRACE_FORMAT(sched_wait_task, +TRACE_EVENT_FORMAT(sched_wait_task, TPPROTO(struct rq *rq, struct task_struct *p), TPARGS(rq, p), - TPFMT("task %s:%d", p->comm, p->pid)); + TPFMT("task %s:%d", p->comm, p->pid), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, p->pid) + ), + TPRAWFMT("task %d") + ); -TRACE_FORMAT(sched_wakeup, +TRACE_EVENT_FORMAT(sched_wakeup, TPPROTO(struct rq *rq, struct task_struct *p, int success), TPARGS(rq, p, success), TPFMT("task %s:%d %s", - p->comm, p->pid, success?"succeeded":"failed")); + p->comm, p->pid, success ? "succeeded" : "failed"), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, p->pid) + TRACE_FIELD(int, success, success) + ), + TPRAWFMT("task %d success=%d") + ); -TRACE_FORMAT(sched_wakeup_new, +TRACE_EVENT_FORMAT(sched_wakeup_new, TPPROTO(struct rq *rq, struct task_struct *p, int success), TPARGS(rq, p, success), TPFMT("task %s:%d", - p->comm, p->pid, success?"succeeded":"failed")); + p->comm, p->pid, success ? "succeeded" : "failed"), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, p->pid) + TRACE_FIELD(int, success, success) + ), + TPRAWFMT("task %d success=%d") + ); -TRACE_FORMAT(sched_switch, +TRACE_EVENT_FORMAT(sched_switch, TPPROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next), TPARGS(rq, prev, next), TPFMT("task %s:%d ==> %s:%d", - prev->comm, prev->pid, next->comm, next->pid)); + prev->comm, prev->pid, next->comm, next->pid), + TRACE_STRUCT( + TRACE_FIELD(pid_t, prev_pid, prev->pid) + TRACE_FIELD(int, prev_prio, prev->prio) + TRACE_FIELD(pid_t, next_pid, next->pid) + TRACE_FIELD(int, next_prio, next->prio) + ), + TPRAWFMT("prev %d:%d ==> next %d:%d") + ); -TRACE_FORMAT(sched_migrate_task, +TRACE_EVENT_FORMAT(sched_migrate_task, TPPROTO(struct task_struct *p, int orig_cpu, int dest_cpu), TPARGS(p, orig_cpu, dest_cpu), TPFMT("task %s:%d from: %d to: %d", - p->comm, p->pid, orig_cpu, dest_cpu)); + p->comm, p->pid, orig_cpu, dest_cpu), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, p->pid) + TRACE_FIELD(int, orig_cpu, orig_cpu) + TRACE_FIELD(int, dest_cpu, dest_cpu) + ), + TPRAWFMT("task %d from: %d to: %d") + ); -TRACE_FORMAT(sched_process_free, +TRACE_EVENT_FORMAT(sched_process_free, TPPROTO(struct task_struct *p), TPARGS(p), - TPFMT("task %s:%d", p->comm, p->pid)); + TPFMT("task %s:%d", p->comm, p->pid), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, p->pid) + ), + TPRAWFMT("task %d") + ); -TRACE_FORMAT(sched_process_exit, +TRACE_EVENT_FORMAT(sched_process_exit, TPPROTO(struct task_struct *p), TPARGS(p), - TPFMT("task %s:%d", p->comm, p->pid)); + TPFMT("task %s:%d", p->comm, p->pid), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, p->pid) + ), + TPRAWFMT("task %d") + ); -TRACE_FORMAT(sched_process_wait, +TRACE_EVENT_FORMAT(sched_process_wait, TPPROTO(struct pid *pid), TPARGS(pid), - TPFMT("pid %d", pid)); + TPFMT("pid %d", pid_nr(pid)), + TRACE_STRUCT( + TRACE_FIELD(pid_t, pid, pid_nr(pid)) + ), + TPRAWFMT("task %d") + ); -TRACE_FORMAT(sched_process_fork, +TRACE_EVENT_FORMAT(sched_process_fork, TPPROTO(struct task_struct *parent, struct task_struct *child), TPARGS(parent, child), TPFMT("parent %s:%d child %s:%d", - parent->comm, parent->pid, child->comm, child->pid)); + parent->comm, parent->pid, child->comm, child->pid), + TRACE_STRUCT( + TRACE_FIELD(pid_t, parent, parent->pid) + TRACE_FIELD(pid_t, child, child->pid) + ), + TPRAWFMT("parent %d child %d") + ); -TRACE_FORMAT(sched_signal_send, +TRACE_EVENT_FORMAT(sched_signal_send, TPPROTO(int sig, struct task_struct *p), TPARGS(sig, p), - TPFMT("sig: %d task %s:%d", sig, p->comm, p->pid)); + TPFMT("sig: %d task %s:%d", sig, p->comm, p->pid), + TRACE_STRUCT( + TRACE_FIELD(int, sig, sig) + TRACE_FIELD(pid_t, pid, p->pid) + ), + TPRAWFMT("sig: %d task %d") + ); #undef TRACE_SYSTEM -- cgit v1.2.2 From f2034f1e1adaac6713a6d48b5a2d4f3aa3e63ccb Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sat, 28 Feb 2009 02:54:39 -0500 Subject: tracing: create the C style tracing for the irq subsystem This patch utilizes the TRACE_EVENT_FORMAT macro to enable the C style faster tracing for the irq subsystem trace points. Signed-off-by: Steven Rostedt --- include/trace/irq_event_types.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h index 47a2be1b2d7d..65850bc5ea06 100644 --- a/include/trace/irq_event_types.h +++ b/include/trace/irq_event_types.h @@ -8,15 +8,26 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM irq -TRACE_FORMAT(irq_handler_entry, +TRACE_EVENT_FORMAT(irq_handler_entry, TPPROTO(int irq, struct irqaction *action), TPARGS(irq, action), - TPFMT("irq=%d handler=%s", irq, action->name)); + TPFMT("irq=%d handler=%s", irq, action->name), + TRACE_STRUCT( + TRACE_FIELD(int, irq, irq) + ), + TPRAWFMT("irq %d") + ); -TRACE_FORMAT(irq_handler_exit, +TRACE_EVENT_FORMAT(irq_handler_exit, TPPROTO(int irq, struct irqaction *action, int ret), TPARGS(irq, action, ret), TPFMT("irq=%d handler=%s return=%s", - irq, action->name, ret ? "handled" : "unhandled")); + irq, action->name, ret ? "handled" : "unhandled"), + TRACE_STRUCT( + TRACE_FIELD(int, irq, irq) + TRACE_FIELD(int, ret, ret) + ), + TPRAWFMT("irq %d ret %d") + ); #undef TRACE_SYSTEM -- cgit v1.2.2