* [uml-devel] [PATCH 1/5] UML: Fix some apparent bitrot
2009-06-16 0:17 [uml-devel] [RFC][PATCH 0/5] UML: Support lockdep on x86-64 UML Paul Menage
@ 2009-06-16 0:17 ` Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 2/5] UML: Enable CONFIG_TRACE_IRQFLAGS_SUPPORT Paul Menage
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul Menage @ 2009-06-16 0:17 UTC (permalink / raw)
To: peterz, mingo, jdike; +Cc: user-mode-linux-devel
UML: Fix some apparent bitrot
- migration of net_device methods into net_device_ops
- address space layout changes
- dma_sync_single() changes
Signed-off-by: Paul Menage <menage@google.com>
---
arch/um/drivers/slip_kern.c | 1 -
arch/um/drivers/slirp_kern.c | 1 -
arch/um/include/asm/dma-mapping.h | 4 ++--
arch/um/include/shared/as-layout.h | 4 +---
4 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 5ec1756..dd2aadc 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -30,7 +30,6 @@ static void slip_init(struct net_device *dev, void *data)
slip_proto_init(&spri->slip);
- dev->init = NULL;
dev->hard_header_len = 0;
dev->header_ops = NULL;
dev->addr_len = 0;
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index f15a6e7..e376284 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -32,7 +32,6 @@ void slirp_init(struct net_device *dev, void *data)
slip_proto_init(&spri->slip);
- dev->init = NULL;
dev->hard_header_len = 0;
dev->header_ops = NULL;
dev->addr_len = 0;
diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h
index 90fc708..378de4b 100644
--- a/arch/um/include/asm/dma-mapping.h
+++ b/arch/um/include/asm/dma-mapping.h
@@ -79,14 +79,14 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
}
static inline void
-dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
BUG();
}
static inline void
-dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
{
BUG();
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
index a92b678..05e4573 100644
--- a/arch/um/include/shared/as-layout.h
+++ b/arch/um/include/shared/as-layout.h
@@ -52,9 +52,7 @@ extern unsigned long end_vm;
extern unsigned long start_vm;
extern unsigned long long highmem;
-extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
-extern unsigned long _unprotected_end;
-extern unsigned long brk_start;
+extern unsigned long _end;
extern unsigned long host_task_size;
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread* [uml-devel] [PATCH 2/5] UML: Enable CONFIG_TRACE_IRQFLAGS_SUPPORT
2009-06-16 0:17 [uml-devel] [RFC][PATCH 0/5] UML: Support lockdep on x86-64 UML Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 1/5] UML: Fix some apparent bitrot Paul Menage
@ 2009-06-16 0:17 ` Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 3/5] UML: Enable CONFIG_STACKTRACE_SUPPORT Paul Menage
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul Menage @ 2009-06-16 0:17 UTC (permalink / raw)
To: peterz, mingo, jdike; +Cc: user-mode-linux-devel
UML: Enable CONFIG_TRACE_IRQFLAGS_SUPPORT
Signed-off-by: Paul Menage <menage@google.com>
---
arch/um/Kconfig.common | 2 +-
arch/um/include/asm/system.h | 39 ++++++++++++++++++++++-----------------
arch/um/kernel/irq.c | 1 +
arch/um/kernel/process.c | 1 -
arch/um/kernel/skas/process.c | 2 +-
5 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 0d207e7..8a54ae4 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -36,7 +36,7 @@ config PCMCIA
# Yet to do!
config TRACE_IRQFLAGS_SUPPORT
bool
- default n
+ default y
config LOCKDEP_SUPPORT
bool
diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h
index 753346e..dd76c29 100644
--- a/arch/um/include/asm/system.h
+++ b/arch/um/include/asm/system.h
@@ -11,23 +11,28 @@ extern int get_signals(void);
extern void block_signals(void);
extern void unblock_signals(void);
-#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
- (flags) = get_signals(); } while(0)
-#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
- set_signals(flags); } while(0)
-
-#define local_irq_save(flags) do { local_save_flags(flags); \
- local_irq_disable(); } while(0)
-
-#define local_irq_enable() unblock_signals()
-#define local_irq_disable() block_signals()
-
-#define irqs_disabled() \
-({ \
- unsigned long flags; \
- local_save_flags(flags); \
- (flags == 0); \
-})
+#define raw_local_save_flags(flags) do { typecheck(unsigned long, flags); \
+ (flags) = get_signals(); } while (0)
+#define raw_local_irq_restore(flags) do { typecheck(unsigned long, flags); \
+ set_signals(flags); } while (0)
+
+#define raw_local_irq_save(flags) do { raw_local_save_flags(flags); \
+ raw_local_irq_disable(); } while (0)
+
+#define raw_local_irq_enable() unblock_signals()
+#define raw_local_irq_disable() block_signals()
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags == 0);
+}
+
+static inline int raw_irqs_disabled(void)
+{
+ unsigned long flags;
+ raw_local_save_flags(flags);
+ return raw_irqs_disabled_flags(flags);
+}
extern void *_switch_to(void *prev, void *next, void *last);
#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 454cdb4..f7374a2 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -80,6 +80,7 @@ void sigio_handler(int sig, struct uml_pt_regs *regs)
if (smp_sigio_handler())
return;
+ trace_hardirqs_off();
while (1) {
n = os_waiting_for_events(active_fds);
if (n <= 0) {
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 4a28a15..c55debf 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -450,4 +450,3 @@ int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu);
}
-
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 2e9852c..4a21c5c 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -35,7 +35,7 @@ static int __init start_kernel_proc(void *unused)
{
int pid;
- block_signals();
+ local_irq_disable();
pid = os_getpid();
cpu_tasks[0].pid = pid;
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread* [uml-devel] [PATCH 3/5] UML: Enable CONFIG_STACKTRACE_SUPPORT
2009-06-16 0:17 [uml-devel] [RFC][PATCH 0/5] UML: Support lockdep on x86-64 UML Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 1/5] UML: Fix some apparent bitrot Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 2/5] UML: Enable CONFIG_TRACE_IRQFLAGS_SUPPORT Paul Menage
@ 2009-06-16 0:17 ` Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 4/5] UML: Avoid lockdep issues during initialization Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 5/5] UML: Remove sigio_lock()/sigio_unlock() lockdep warnings Paul Menage
4 siblings, 0 replies; 6+ messages in thread
From: Paul Menage @ 2009-06-16 0:17 UTC (permalink / raw)
To: peterz, mingo, jdike; +Cc: user-mode-linux-devel
UML: Enable CONFIG_STACKTRACE_SUPPORT
Adds a simple stacktrace function, only tested/enabled on X86
Signed-off-by: Paul Menage <menage@google.com>
---
arch/um/Kconfig.common | 2 +
arch/um/kernel/Makefile | 1 +
arch/um/kernel/stacktrace.c | 68 +++++++++++++++++++++++++++++++++++++++++++
arch/um/kernel/sysrq.c | 20 +++++++++++++
4 files changed, 90 insertions(+), 1 deletions(-)
create mode 100644 arch/um/kernel/stacktrace.c
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 8a54ae4..b757c36 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -44,7 +44,7 @@ config LOCKDEP_SUPPORT
config STACKTRACE_SUPPORT
bool
- default n
+ default UML_X86
config GENERIC_CALIBRATE_DELAY
bool
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 388ec0a..b1867a0 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -14,6 +14,7 @@ obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
obj-$(CONFIG_GCOV) += gmon_syms.o
+obj-$(CONFIG_STACKTRACE_SUPPORT) += stacktrace.o
USER_OBJS := config.o
diff --git a/arch/um/kernel/stacktrace.c b/arch/um/kernel/stacktrace.c
new file mode 100644
index 0000000..a0d6a60
--- /dev/null
+++ b/arch/um/kernel/stacktrace.c
@@ -0,0 +1,68 @@
+/*
+ * Simple stacktrace function. Only tested on x86, but can probably
+ * be adapted to other architectures with minimal work. (E.g. checking
+ * stack direction)
+ */
+#include "linux/stddef.h"
+#include <linux/stacktrace.h>
+#include <linux/kallsyms.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+static void save_stack_address(unsigned long addr, struct stack_trace *trace)
+{
+ if (!__kernel_text_address(addr))
+ return;
+
+ if (trace->skip) {
+ trace->skip--;
+ return;
+ }
+
+ trace->entries[trace->nr_entries++] = addr;
+}
+
+#define THREAD_MASK (THREAD_SIZE-1)
+
+#ifdef CONFIG_FRAME_POINTER
+
+struct stack_frame {
+ struct stack_frame *next_frame;
+ unsigned long return_address;
+};
+
+void save_stack_trace(struct stack_trace *trace)
+{
+ unsigned long addr;
+ struct stack_frame *frame, *end;
+ frame = __builtin_frame_address(0);
+ end = (struct stack_frame *)
+ ((((unsigned long)frame) + THREAD_MASK) & ~THREAD_MASK);
+ while (trace->nr_entries < trace->max_entries) {
+ addr = frame->return_address;
+ save_stack_address(addr, trace);
+ if (frame->next_frame <= frame || frame->next_frame > end)
+ break;
+ frame = frame->next_frame;
+ }
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+#else
+
+void save_stack_trace(struct stack_trace *trace)
+{
+ unsigned long addr;
+ unsigned long *stack = (unsigned long *)&stack;
+ while (trace->nr_entries < trace->max_entries) {
+ addr = *stack;
+ save_stack_address(addr, trace);
+ stack++;
+ if (!(stack & THREAD_MASK))
+ break;
+ }
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+#endif
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 56d43d0..42b832c 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -11,6 +11,25 @@
/* Catch non-i386 SUBARCH's. */
#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
+#ifdef CONFIG_STACKTRACE
+void show_trace(struct task_struct *task, unsigned long * stack)
+{
+ struct stack_trace trace;
+ unsigned long entries[64];
+
+ if (!stack) {
+ stack = (unsigned long *) &stack;
+ WARN_ON(1);
+ }
+
+ trace.nr_entries = 0;
+ trace.max_entries = ARRAY_SIZE(entries);
+ trace.entries = entries;
+ trace.skip = 0;
+ save_stack_trace(&trace);
+ print_stack_trace(&trace, 0);
+}
+#else
void show_trace(struct task_struct *task, unsigned long * stack)
{
unsigned long addr;
@@ -33,6 +52,7 @@ void show_trace(struct task_struct *task, unsigned long * stack)
}
printk(KERN_INFO "\n");
}
+#endif /& CONFIG_STACKTRACE */
#endif
/*
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread* [uml-devel] [PATCH 4/5] UML: Avoid lockdep issues during initialization
2009-06-16 0:17 [uml-devel] [RFC][PATCH 0/5] UML: Support lockdep on x86-64 UML Paul Menage
` (2 preceding siblings ...)
2009-06-16 0:17 ` [uml-devel] [PATCH 3/5] UML: Enable CONFIG_STACKTRACE_SUPPORT Paul Menage
@ 2009-06-16 0:17 ` Paul Menage
2009-06-16 0:17 ` [uml-devel] [PATCH 5/5] UML: Remove sigio_lock()/sigio_unlock() lockdep warnings Paul Menage
4 siblings, 0 replies; 6+ messages in thread
From: Paul Menage @ 2009-06-16 0:17 UTC (permalink / raw)
To: peterz, mingo, jdike; +Cc: user-mode-linux-devel
UML: Avoid lockdep issues during initialization
UML calls atomic_notifier_chain_register() very early during
initialization. When lockdep is in use, the spinlock operations thus
invoked make use of current_thread_info(), which isn't valid in UML
until start_kernel_proc() is reached (running on the init_thread_union
stack rather than the default stack at the top of the address space).
This patch moves the call to the beginning of start_kernel_proc(), and
additionally disables lock debugging for the duration of the call,
since lockdep_init() doesn't occur until start_kernel() is called.
Signed-off-by: Paul Menage <menage@google.com>
---
arch/um/kernel/skas/process.c | 26 ++++++++++++++++++++++++++
arch/um/kernel/um_arch.c | 20 --------------------
2 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 4a21c5c..2b62a72 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -5,7 +5,9 @@
#include "linux/init.h"
#include "linux/sched.h"
+#include "linux/debug_locks.h"
#include "as-layout.h"
+#include "shared/kern_util.h"
#include "kern.h"
#include "os.h"
#include "skas.h"
@@ -31,10 +33,34 @@ int new_mm(unsigned long stack)
extern void start_kernel(void);
+static int panic_exit(struct notifier_block *self, unsigned long unused1,
+ void *unused2)
+{
+ bust_spinlocks(1);
+ show_regs(&(current->thread.regs));
+ bust_spinlocks(0);
+ uml_exitcode = 1;
+ os_dump_core();
+ return 0;
+}
+
+static struct notifier_block panic_exit_notifier = {
+ .notifier_call = panic_exit,
+ .next = NULL,
+ .priority = 0
+};
+
static int __init start_kernel_proc(void *unused)
{
int pid;
+ /* lockdep hasn't yet been initialized, but this call takes
+ * spinlocks. Temporarily disable lock debugging */
+ int saved_debug_locks = debug_locks;
+ debug_locks = 0;
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &panic_exit_notifier);
+ debug_locks = saved_debug_locks;
local_irq_disable();
pid = os_getpid();
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 8d84250..364c589 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -223,23 +223,6 @@ static void __init uml_postsetup(void)
return;
}
-static int panic_exit(struct notifier_block *self, unsigned long unused1,
- void *unused2)
-{
- bust_spinlocks(1);
- show_regs(&(current->thread.regs));
- bust_spinlocks(0);
- uml_exitcode = 1;
- os_dump_core();
- return 0;
-}
-
-static struct notifier_block panic_exit_notifier = {
- .notifier_call = panic_exit,
- .next = NULL,
- .priority = 0
-};
-
/* Set during early boot */
unsigned long task_size;
EXPORT_SYMBOL(task_size);
@@ -360,9 +343,6 @@ int __init linux_main(int argc, char **argv)
printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size);
- atomic_notifier_chain_register(&panic_notifier_list,
- &panic_exit_notifier);
-
uml_postsetup();
stack_protections((unsigned long) &init_thread_info);
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread* [uml-devel] [PATCH 5/5] UML: Remove sigio_lock()/sigio_unlock() lockdep warnings
2009-06-16 0:17 [uml-devel] [RFC][PATCH 0/5] UML: Support lockdep on x86-64 UML Paul Menage
` (3 preceding siblings ...)
2009-06-16 0:17 ` [uml-devel] [PATCH 4/5] UML: Avoid lockdep issues during initialization Paul Menage
@ 2009-06-16 0:17 ` Paul Menage
4 siblings, 0 replies; 6+ messages in thread
From: Paul Menage @ 2009-06-16 0:17 UTC (permalink / raw)
To: peterz, mingo, jdike; +Cc: user-mode-linux-devel
UML: Remove sigio_lock()/sigio_unlock() lockdep warnings
When lockdep is enabled on UML, calls to sigio_lock() and
sigio_unlock() trigger a lockdep warning since this function is called
both from interrupt context and process context. This patch allows a
"flags" argument to be passed to sigio_lock() and sigio_unlock() to
allow them to use spin_lock_irqsave() and spin_unlock_irqrestore().
Signed-off-by: Paul Menage <menage@google.com>
---
arch/um/include/shared/sigio.h | 4 +--
arch/um/kernel/sigio.c | 8 +++---
arch/um/os-Linux/sigio.c | 55 +++++++++++++++++++++-------------------
3 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/arch/um/include/shared/sigio.h b/arch/um/include/shared/sigio.h
index 434f1a9..5b16047 100644
--- a/arch/um/include/shared/sigio.h
+++ b/arch/um/include/shared/sigio.h
@@ -8,7 +8,7 @@
extern int write_sigio_irq(int fd);
extern int register_sigio_fd(int fd);
-extern void sigio_lock(void);
-extern void sigio_unlock(void);
+extern void sigio_lock(unsigned long *flags);
+extern void sigio_unlock(unsigned long flags);
#endif
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c
index 2b272b6..f258501 100644
--- a/arch/um/kernel/sigio.c
+++ b/arch/um/kernel/sigio.c
@@ -39,12 +39,12 @@ int write_sigio_irq(int fd)
/* These are called from os-Linux/sigio.c to protect its pollfds arrays. */
static DEFINE_SPINLOCK(sigio_spinlock);
-void sigio_lock(void)
+void sigio_lock(unsigned long *flags)
{
- spin_lock(&sigio_spinlock);
+ spin_lock_irqsave(&sigio_spinlock, *flags);
}
-void sigio_unlock(void)
+void sigio_unlock(unsigned long flags)
{
- spin_unlock(&sigio_spinlock);
+ spin_unlock_irqrestore(&sigio_spinlock, flags);
}
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 63d299d..aa85a5c 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -24,6 +24,8 @@
* Protected by sigio_lock(), also used by sigio_cleanup, which is an
* exitcall.
*/
+
+/* -1 => uninitialized, -2 => initializing */
static int write_sigio_pid = -1;
static unsigned long write_sigio_stack;
@@ -171,8 +173,9 @@ int add_sigio_fd(int fd)
{
struct pollfd *p;
int err = 0, i, n;
+ unsigned long flags;
- sigio_lock();
+ sigio_lock(&flags);
for (i = 0; i < all_sigio_fds.used; i++) {
if (all_sigio_fds.poll[i].fd == fd)
break;
@@ -198,7 +201,7 @@ int add_sigio_fd(int fd)
next_poll.used = n + 1;
update_thread();
out:
- sigio_unlock();
+ sigio_unlock(flags);
return err;
}
@@ -206,6 +209,7 @@ int ignore_sigio_fd(int fd)
{
struct pollfd *p;
int err = 0, i, n = 0;
+ unsigned long flags;
/*
* This is called from exitcalls elsewhere in UML - if
@@ -215,7 +219,7 @@ int ignore_sigio_fd(int fd)
if (write_sigio_pid == -1)
return -EIO;
- sigio_lock();
+ sigio_lock(&flags);
for (i = 0; i < current_poll.used; i++) {
if (current_poll.poll[i].fd == fd)
break;
@@ -236,7 +240,7 @@ int ignore_sigio_fd(int fd)
update_thread();
out:
- sigio_unlock();
+ sigio_unlock(flags);
return err;
}
@@ -262,15 +266,20 @@ static void write_sigio_workaround(void)
int err;
int l_write_sigio_fds[2];
int l_sigio_private[2];
- int l_write_sigio_pid;
+ unsigned long flags;
/* We call this *tons* of times - and most ones we must just fail. */
- sigio_lock();
- l_write_sigio_pid = write_sigio_pid;
- sigio_unlock();
-
- if (l_write_sigio_pid != -1)
+ again:
+ sigio_lock(&flags);
+ if (write_sigio_pid >= 0) {
+ sigio_unlock(flags);
return;
+ } else if (write_sigio_pid == -2) {
+ sigio_unlock(flags);
+ goto again;
+ }
+ write_sigio_pid = -2;
+ sigio_unlock(flags);
err = os_pipe(l_write_sigio_fds, 1, 1);
if (err < 0) {
@@ -289,22 +298,16 @@ static void write_sigio_workaround(void)
if (!p)
goto out_close2;
- sigio_lock();
-
- /*
- * Did we race? Don't try to optimize this, please, it's not so likely
- * to happen, and no more than once at the boot.
- */
- if (write_sigio_pid != -1)
- goto out_free;
+ if (write_sigio_irq(l_write_sigio_fds[0])) {
+ sigio_lock(&flags);
+ goto out_clear_poll;
+ }
+ sigio_lock(&flags);
current_poll = ((struct pollfds) { .poll = p,
.used = 1,
.size = 1 });
- if (write_sigio_irq(l_write_sigio_fds[0]))
- goto out_clear_poll;
-
memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
@@ -315,7 +318,7 @@ static void write_sigio_workaround(void)
if (write_sigio_pid < 0)
goto out_clear;
- sigio_unlock();
+ sigio_unlock(flags);
return;
out_clear:
@@ -328,9 +331,8 @@ out_clear_poll:
current_poll = ((struct pollfds) { .poll = NULL,
.size = 0,
.used = 0 });
-out_free:
- sigio_unlock();
kfree(p);
+ sigio_unlock(flags);
out_close2:
close(l_sigio_private[0]);
close(l_sigio_private[1]);
@@ -342,10 +344,11 @@ out_close1:
void sigio_broken(int fd, int read)
{
int err;
+ unsigned long flags;
write_sigio_workaround();
- sigio_lock();
+ sigio_lock(&flags);
err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
if (err) {
printk(UM_KERN_ERR "maybe_sigio_broken - failed to add pollfd "
@@ -358,7 +361,7 @@ void sigio_broken(int fd, int read)
.events = read ? POLLIN : POLLOUT,
.revents = 0 });
out:
- sigio_unlock();
+ sigio_unlock(flags);
}
/* Changed during early boot */
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread