* [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-06-03 12:44 [RFC 0/3]: hvc_console rework for platform without hard irqs Christian Borntraeger
@ 2008-06-03 12:45 ` Christian Borntraeger
2008-06-04 0:13 ` Rusty Russell
2008-10-13 5:16 ` Benjamin Herrenschmidt
2008-06-03 12:46 ` [RFC 2/3] virtio_console: use virtqueue notification for hvc_console Christian Borntraeger
` (5 subsequent siblings)
6 siblings, 2 replies; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-03 12:45 UTC (permalink / raw)
To: Linux PPC devel
Cc: Virtualization Mailing List, Jeremy Fitzhardinge, Rusty Russell,
LKML
This patch tries to change hvc_console to not use request_irq/free_irq if
the backend does not use irqs. This allows virtio_console to use hvc_console
without having a linker reference to request_irq/free_irq.
The irq specific code is moved to hvc_irq.c and selected by the drivers that
use irqs (System p, System i, XEN).
I replaced "irq" with the opaque name "data". The request_irq and free_irq
calls are replaced with notifier_add and notifier_del. I have also changed
the code a bit to call the notifier_add and notifier_del inside the spinlock
area as the callbacks are found via hp->ops.
Feedback is appreciated.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
drivers/char/Kconfig | 8 ++++
drivers/char/Makefile | 1
drivers/char/hvc_console.c | 80
++++++++++-----------------------------------
drivers/char/hvc_console.h | 34 ++++++++++++++++---
drivers/char/hvc_irq.c | 37 ++++++++++++++++++++
drivers/char/hvc_iseries.c | 2 +
drivers/char/hvc_vio.c | 2 +
drivers/char/hvc_xen.c | 2 +
8 files changed, 100 insertions(+), 66 deletions(-)
Index: kvm/drivers/char/Kconfig
===================================================================
--- kvm.orig/drivers/char/Kconfig
+++ kvm/drivers/char/Kconfig
@@ -588,11 +588,17 @@ config HVC_DRIVER
It will automatically be selected if one of the back-end console drivers
is selected.
+config HVC_IRQ
+ bool
+ help
+ Infrastructure for using the IRQ code for HVC console.
+ It will automatically be selected by the drivers that need it.
config HVC_CONSOLE
bool "pSeries Hypervisor Virtual Console support"
depends on PPC_PSERIES
select HVC_DRIVER
+ select HVC_IRQ
help
pSeries machines when partitioned support a hypervisor virtual
console. This driver allows each pSeries partition to have a console
@@ -603,6 +609,7 @@ config HVC_ISERIES
depends on PPC_ISERIES
default y
select HVC_DRIVER
+ select HVC_IRQ
help
iSeries machines support a hypervisor virtual console.
@@ -624,6 +631,7 @@ config HVC_XEN
bool "Xen Hypervisor Console support"
depends on XEN
select HVC_DRIVER
+ select HVC_IRQ
default y
help
Xen virtual console device driver
Index: kvm/drivers/char/Makefile
===================================================================
--- kvm.orig/drivers/char/Makefile
+++ kvm/drivers/char/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_HVC_ISERIES) += hvc_iseries
obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
+obj-$(CONFIG_HVC_IRQ) += hvc_irq.o
obj-$(CONFIG_HVC_XEN) += hvc_xen.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
Index: kvm/drivers/char/hvc_console.c
===================================================================
--- kvm.orig/drivers/char/hvc_console.c
+++ kvm/drivers/char/hvc_console.c
@@ -75,23 +75,6 @@ static int hvc_init(void);
static int sysrq_pressed;
#endif
-struct hvc_struct {
- spinlock_t lock;
- int index;
- struct tty_struct *tty;
- unsigned int count;
- int do_wakeup;
- char *outbuf;
- int outbuf_size;
- int n_outbuf;
- uint32_t vtermno;
- struct hv_ops *ops;
- int irq_requested;
- int irq;
- struct list_head next;
- struct kref kref; /* ref count & hvc_struct lifetime */
-};
-
/* dynamic list of hvc_struct instances */
static LIST_HEAD(hvc_structs);
@@ -300,26 +283,12 @@ int hvc_instantiate(uint32_t vtermno, in
}
/* Wake the sleeping khvcd */
-static void hvc_kick(void)
+void hvc_kick(void)
{
hvc_kicked = 1;
wake_up_process(hvc_task);
}
-static int hvc_poll(struct hvc_struct *hp);
-
-/*
- * NOTE: This API isn't used if the console adapter doesn't support
interrupts.
- * In this case the console is poll driven.
- */
-static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
-{
- /* if hvc_poll request a repoll, then kick the hvcd thread */
- if (hvc_poll(dev_instance))
- hvc_kick();
- return IRQ_HANDLED;
-}
-
static void hvc_unthrottle(struct tty_struct *tty)
{
hvc_kick();
@@ -333,7 +302,6 @@ static int hvc_open(struct tty_struct *t
{
struct hvc_struct *hp;
unsigned long flags;
- int irq = 0;
int rc = 0;
/* Auto increments kref reference if found. */
@@ -352,18 +320,15 @@ static int hvc_open(struct tty_struct *t
tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */
hp->tty = tty;
- /* Save for request_irq outside of spin_lock. */
- irq = hp->irq;
- if (irq)
- hp->irq_requested = 1;
+
+ if (hp->ops->notifier_add)
+ rc = hp->ops->notifier_add(hp, hp->data);
spin_unlock_irqrestore(&hp->lock, flags);
- /* check error, fallback to non-irq */
- if (irq)
- rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, "hvc_console",
hp);
+
/*
- * If the request_irq() fails and we return an error. The tty layer
+ * If the notifier fails we return an error. The tty layer
* will call hvc_close() after a failed open but we don't want to clean
* up there so we'll clean up here and clear out the previously set
* tty fields and return the kref reference.
@@ -371,7 +336,6 @@ static int hvc_open(struct tty_struct *t
if (rc) {
spin_lock_irqsave(&hp->lock, flags);
hp->tty = NULL;
- hp->irq_requested = 0;
spin_unlock_irqrestore(&hp->lock, flags);
tty->driver_data = NULL;
kref_put(&hp->kref, destroy_hvc_struct);
@@ -386,7 +350,6 @@ static int hvc_open(struct tty_struct *t
static void hvc_close(struct tty_struct *tty, struct file * filp)
{
struct hvc_struct *hp;
- int irq = 0;
unsigned long flags;
if (tty_hung_up_p(filp))
@@ -404,9 +367,8 @@ static void hvc_close(struct tty_struct
spin_lock_irqsave(&hp->lock, flags);
if (--hp->count == 0) {
- if (hp->irq_requested)
- irq = hp->irq;
- hp->irq_requested = 0;
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
/* We are done with the tty pointer now. */
hp->tty = NULL;
@@ -418,10 +380,6 @@ static void hvc_close(struct tty_struct
* waking periodically to check chars_in_buffer().
*/
tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
-
- if (irq)
- free_irq(irq, hp);
-
} else {
if (hp->count < 0)
printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
@@ -436,7 +394,6 @@ static void hvc_hangup(struct tty_struct
{
struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
- int irq = 0;
int temp_open_count;
if (!hp)
@@ -458,13 +415,12 @@ static void hvc_hangup(struct tty_struct
hp->count = 0;
hp->n_outbuf = 0;
hp->tty = NULL;
- if (hp->irq_requested)
- /* Saved for use outside of spin_lock. */
- irq = hp->irq;
- hp->irq_requested = 0;
+
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
+
spin_unlock_irqrestore(&hp->lock, flags);
- if (irq)
- free_irq(irq, hp);
+
while(temp_open_count) {
--temp_open_count;
kref_put(&hp->kref, destroy_hvc_struct);
@@ -575,7 +531,7 @@ static u32 timeout = MIN_TIMEOUT;
#define HVC_POLL_READ 0x00000001
#define HVC_POLL_WRITE 0x00000002
-static int hvc_poll(struct hvc_struct *hp)
+int hvc_poll(struct hvc_struct *hp)
{
struct tty_struct *tty;
int i, n, poll_mask = 0;
@@ -602,10 +558,10 @@ static int hvc_poll(struct hvc_struct *h
if (test_bit(TTY_THROTTLED, &tty->flags))
goto throttled;
- /* If we aren't interrupt driven and aren't throttled, we always
+ /* If we aren't notifier driven and aren't throttled, we always
* request a reschedule
*/
- if (hp->irq == 0)
+ if (!hp->ops->notifier_add)
poll_mask |= HVC_POLL_READ;
/* Read data if any */
@@ -739,7 +695,7 @@ static const struct tty_operations hvc_o
.chars_in_buffer = hvc_chars_in_buffer,
};
-struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
+struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size)
{
struct hvc_struct *hp;
@@ -760,7 +716,7 @@ struct hvc_struct __devinit *hvc_alloc(u
memset(hp, 0x00, sizeof(*hp));
hp->vtermno = vtermno;
- hp->irq = irq;
+ hp->data = data;
hp->ops = ops;
hp->outbuf_size = outbuf_size;
hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
Index: kvm/drivers/char/hvc_console.h
===================================================================
--- kvm.orig/drivers/char/hvc_console.h
+++ kvm/drivers/char/hvc_console.h
@@ -42,22 +42,48 @@
*/
#define HVC_ALLOC_TTY_ADAPTERS 8
+struct hvc_struct {
+ spinlock_t lock;
+ int index;
+ struct tty_struct *tty;
+ unsigned int count;
+ int do_wakeup;
+ char *outbuf;
+ int outbuf_size;
+ int n_outbuf;
+ uint32_t vtermno;
+ struct hv_ops *ops;
+ int data;
+ struct list_head next;
+ struct kref kref; /* ref count & hvc_struct lifetime */
+};
/* implemented by a low level driver */
struct hv_ops {
int (*get_chars)(uint32_t vtermno, char *buf, int count);
int (*put_chars)(uint32_t vtermno, const char *buf, int count);
-};
-struct hvc_struct;
+ /* Callbacks for notification. Called in open and close */
+ int (*notifier_add)(struct hvc_struct *hp, int data);
+ void (*notifier_del)(struct hvc_struct *hp, int data);
+};
/* Register a vterm and a slot index for use as a console (console_init) */
extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
/* register a vterm for hvc tty operation (module_init or hotplug add) */
-extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
+extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size);
-/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
+/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
extern int __devexit hvc_remove(struct hvc_struct *hp);
+/* data available */
+int hvc_poll(struct hvc_struct *hp);
+void hvc_kick(void);
+
+#ifdef CONFIG_HVC_IRQ
+/* default notifier for irq based notification */
+extern int notifier_add_irq(struct hvc_struct *hp, int irq);
+extern void notifier_del_irq(struct hvc_struct *hp, int irq);
+#endif
#endif // HVC_CONSOLE_H
Index: kvm/drivers/char/hvc_irq.c
===================================================================
--- /dev/null
+++ kvm/drivers/char/hvc_irq.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright IBM Corp. 2001,2008
+ *
+ * This file contains the IRQ specific code for hvc_console
+ *
+ */
+
+#include <linux/interrupt.h>
+
+#include "hvc_console.h"
+
+static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
+{
+ /* if hvc_poll request a repoll, then kick the hvcd thread */
+ if (hvc_poll(dev_instance))
+ hvc_kick();
+ return IRQ_HANDLED;
+}
+
+/*
+ * For IRQ based systems these callbacks can be used
+ */
+int notifier_add_irq(struct hvc_struct *hp, int irq)
+{
+ if (!irq)
+ return 0;
+ return request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED,
+ "hvc_console", hp);
+}
+
+void notifier_del_irq(struct hvc_struct *hp, int irq)
+{
+ if (!irq)
+ return;
+ free_irq(irq, hp);
+}
+
Index: kvm/drivers/char/hvc_iseries.c
===================================================================
--- kvm.orig/drivers/char/hvc_iseries.c
+++ kvm/drivers/char/hvc_iseries.c
@@ -200,6 +200,8 @@ done:
static struct hv_ops hvc_get_put_ops = {
.get_chars = get_chars,
.put_chars = put_chars,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
Index: kvm/drivers/char/hvc_vio.c
===================================================================
--- kvm.orig/drivers/char/hvc_vio.c
+++ kvm/drivers/char/hvc_vio.c
@@ -80,6 +80,8 @@ static int filtered_get_chars(uint32_t v
static struct hv_ops hvc_get_put_ops = {
.get_chars = filtered_get_chars,
.put_chars = hvc_put_chars,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
Index: kvm/drivers/char/hvc_xen.c
===================================================================
--- kvm.orig/drivers/char/hvc_xen.c
+++ kvm/drivers/char/hvc_xen.c
@@ -95,6 +95,8 @@ static int read_console(uint32_t vtermno
static struct hv_ops hvc_ops = {
.get_chars = read_console,
.put_chars = write_console,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __init xen_init(void)
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-06-03 12:45 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks Christian Borntraeger
@ 2008-06-04 0:13 ` Rusty Russell
2008-06-04 11:15 ` Christian Borntraeger
2008-10-13 5:16 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 24+ messages in thread
From: Rusty Russell @ 2008-06-04 0:13 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Linux PPC devel, Jeremy Fitzhardinge, LKML,
Virtualization Mailing List
On Tuesday 03 June 2008 22:45:22 Christian Borntraeger wrote:
> This patch tries to change hvc_console to not use request_irq/free_irq if
> the backend does not use irqs. This allows virtio_console to use
> hvc_console without having a linker reference to request_irq/free_irq.
Two questions. Is it possible to make the timer backoff a third kind of
notifier? And is it possible to make the dependency static, rather than
dynamic, or does someone need two options at runtime?
Thanks,
Rusty.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-06-04 0:13 ` Rusty Russell
@ 2008-06-04 11:15 ` Christian Borntraeger
0 siblings, 0 replies; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-04 11:15 UTC (permalink / raw)
To: Rusty Russell
Cc: Linux PPC devel, Jeremy Fitzhardinge, LKML,
Virtualization Mailing List
Am Mittwoch, 4. Juni 2008 schrieb Rusty Russell:
> Two questions. Is it possible to make the timer backoff a third kind of
> notifier?
I can try. The timer handling code is sprinkled a bit in hvc_console but it
should be possible.
> And is it possible to make the dependency static, rather than
> dynamic, or does someone need two options at runtime?
Not sure. Some drivers pass get the irq number from another component. If the
number is 0, the console is poll driven, otherwise irq driven.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-06-03 12:45 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks Christian Borntraeger
2008-06-04 0:13 ` Rusty Russell
@ 2008-10-13 5:16 ` Benjamin Herrenschmidt
2008-10-13 7:51 ` Christian Borntraeger
1 sibling, 1 reply; 24+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-13 5:16 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
On Tue, 2008-06-03 at 14:45 +0200, Christian Borntraeger wrote:
> This patch tries to change hvc_console to not use request_irq/free_irq if
> the backend does not use irqs. This allows virtio_console to use hvc_console
> without having a linker reference to request_irq/free_irq.
>
> The irq specific code is moved to hvc_irq.c and selected by the drivers that
> use irqs (System p, System i, XEN).
>
> I replaced "irq" with the opaque name "data". The request_irq and free_irq
> calls are replaced with notifier_add and notifier_del. I have also changed
> the code a bit to call the notifier_add and notifier_del inside the spinlock
> area as the callbacks are found via hp->ops.
That's causing lockdep to scream, though I have a hard time figuring
out what it thinks is wrong...
Ingo, would you mind giving a hand parsing that output ? Thanks !
Cheers,
Ben.
console [udbg0] enabled
pSeries detected, looking for LPAR capability...
-> fw_feature_init()
<- fw_feature_init()
Machine is LPAR !
Using pSeries machine description
Page orders: linear mapping = 24, virtual = 12, io = 12, vmemmap = 24
-> pSeries_init_early()
-> fw_cmo_feature_init()
CMO not available
<- fw_cmo_feature_init()
<- pSeries_init_early()
Partition configured for 32 cpus.
CPU maps initialized for 2 threads per core
(thread shift is 1)
Starting Linux PPC64 #22 SMP Mon Oct 13 14:18:44 EST 2008
-----------------------------------------------------
ppc64_pft_size = 0x1b
physicalMemorySize = 0x80000000
htab_hash_mask = 0xfffff
-----------------------------------------------------
Linux version 2.6.27-rc5-test (benh@grosgo) (gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7)) #22 SMP Mon Oct 13 14:18:44 EST 2008
[boot]0012 Setup Arch
Node 0 Memory: 0x0-0x44000000
Node 1 Memory: 0x44000000-0x80000000
-> smp_init_pSeries()
<- smp_init_pSeries()
EEH: No capable adapters found
PPC64 nvram contains 7168 bytes
Using shared processor idle loop
Zone PFN ranges:
DMA 0x00000000 -> 0x00008000
Normal 0x00008000 -> 0x00008000
Movable zone start PFN for each node
early_node_map[2] active PFN ranges
0: 0x00000000 -> 0x00004400
1: 0x00004400 -> 0x00008000
On node 0 totalpages: 17408
DMA zone: 17382 pages, LIFO batch:1
On node 1 totalpages: 15360
DMA zone: 15337 pages, LIFO batch:1
[boot]0015 Setup Done
Built 2 zonelists in Node order, mobility grouping on. Total pages: 32719
Policy zone: DMA
Kernel command line: root=/dev/sdb1
[boot]0020 XICS Init
[boot]0021 XICS Done
pic: no ISA interrupt controller
PID hash table entries: 4096 (order: 12, 32768 bytes)
time_init: decrementer frequency = 188.046000 MHz
time_init: processor frequency = 1502.496000 MHz
clocksource: timebase mult[154579e] shift[22] registered
clockevent: decrementer mult[3023] shift[16] cpu[0]
Console: colour dummy device 80x25
console handover: boot [udbg0] -> real [hvc0]
Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
... MAX_LOCKDEP_SUBCLASSES: 8
... MAX_LOCK_DEPTH: 48
... MAX_LOCKDEP_KEYS: 8191
... CLASSHASH_SIZE: 4096
... MAX_LOCKDEP_ENTRIES: 8192
... MAX_LOCKDEP_CHAINS: 16384
... CHAINHASH_SIZE: 8192
memory used by lock dependency info: 4095 kB
per task-struct memory footprint: 2688 bytes
------------------------
| Locking API testsuite:
----------------------------------------------------------------------------
| spin |wlock |rlock |mutex | wsem | rsem |
--------------------------------------------------------------------------
A-A deadlock: ok | ok | ok | ok | ok | ok |
A-B-B-A deadlock: ok | ok | ok | ok | ok | ok |
A-B-B-C-C-A deadlock: ok | ok | ok | ok | ok | ok |
A-B-C-A-B-C deadlock: ok | ok | ok | ok | ok | ok |
A-B-B-C-C-D-D-A deadlock: ok | ok | ok | ok | ok | ok |
A-B-C-D-B-D-D-A deadlock: ok | ok | ok | ok | ok | ok |
A-B-C-D-B-C-D-A deadlock: ok | ok | ok | ok | ok | ok |
double unlock: ok | ok | ok | ok | ok | ok |
initialize held: ok | ok | ok | ok | ok | ok |
bad unlock order: ok | ok | ok | ok | ok | ok |
--------------------------------------------------------------------------
recursive read-lock: | ok | | ok |
recursive read-lock #2: | ok | | ok |
mixed read-write-lock: | ok | | ok |
mixed write-read-lock: | ok | | ok |
--------------------------------------------------------------------------
hard-irqs-on + irq-safe-A/12: ok | ok | ok |
soft-irqs-on + irq-safe-A/12: ok | ok | ok |
hard-irqs-on + irq-safe-A/21: ok | ok | ok |
soft-irqs-on + irq-safe-A/21: ok | ok | ok |
sirq-safe-A => hirqs-on/12: ok | ok | ok |
sirq-safe-A => hirqs-on/21: ok | ok | ok |
hard-safe-A + irqs-on/12: ok | ok | ok |
soft-safe-A + irqs-on/12: ok | ok | ok |
hard-safe-A + irqs-on/21: ok | ok | ok |
soft-safe-A + irqs-on/21: ok | ok | ok |
hard-safe-A + unsafe-B #1/123: ok | ok | ok |
soft-safe-A + unsafe-B #1/123: ok | ok | ok |
hard-safe-A + unsafe-B #1/132: ok | ok | ok |
soft-safe-A + unsafe-B #1/132: ok | ok | ok |
hard-safe-A + unsafe-B #1/213: ok | ok | ok |
soft-safe-A + unsafe-B #1/213: ok | ok | ok |
hard-safe-A + unsafe-B #1/231: ok | ok | ok |
soft-safe-A + unsafe-B #1/231: ok | ok | ok |
hard-safe-A + unsafe-B #1/312: ok | ok | ok |
soft-safe-A + unsafe-B #1/312: ok | ok | ok |
hard-safe-A + unsafe-B #1/321: ok | ok | ok |
soft-safe-A + unsafe-B #1/321: ok | ok | ok |
hard-safe-A + unsafe-B #2/123: ok | ok | ok |
soft-safe-A + unsafe-B #2/123: ok | ok | ok |
hard-safe-A + unsafe-B #2/132: ok | ok | ok |
soft-safe-A + unsafe-B #2/132: ok | ok | ok |
hard-safe-A + unsafe-B #2/213: ok | ok | ok |
soft-safe-A + unsafe-B #2/213: ok | ok | ok |
hard-safe-A + unsafe-B #2/231: ok | ok | ok |
soft-safe-A + unsafe-B #2/231: ok | ok | ok |
hard-safe-A + unsafe-B #2/312: ok | ok | ok |
soft-safe-A + unsafe-B #2/312: ok | ok | ok |
hard-safe-A + unsafe-B #2/321: ok | ok | ok |
soft-safe-A + unsafe-B #2/321: ok | ok | ok |
hard-irq lock-inversion/123: ok | ok | ok |
soft-irq lock-inversion/123: ok | ok | ok |
hard-irq lock-inversion/132: ok | ok | ok |
soft-irq lock-inversion/132: ok | ok | ok |
hard-irq lock-inversion/213: ok | ok | ok |
soft-irq lock-inversion/213: ok | ok | ok |
hard-irq lock-inversion/231: ok | ok | ok |
soft-irq lock-inversion/231: ok | ok | ok |
hard-irq lock-inversion/312: ok | ok | ok |
soft-irq lock-inversion/312: ok | ok | ok |
hard-irq lock-inversion/321: ok | ok | ok |
soft-irq lock-inversion/321: ok | ok | ok |
hard-irq read-recursion/123: ok |
soft-irq read-recursion/123: ok |
hard-irq read-recursion/132: ok |
soft-irq read-recursion/132: ok |
hard-irq read-recursion/213: ok |
soft-irq read-recursion/213: ok |
hard-irq read-recursion/231: ok |
soft-irq read-recursion/231: ok |
hard-irq read-recursion/312: ok |
soft-irq read-recursion/312: ok |
hard-irq read-recursion/321: ok |
soft-irq read-recursion/321: ok |
-------------------------------------------------------
Good, all 218 testcases passed! |
---------------------------------
Dentry cache hash table entries: 262144 (order: 5, 2097152 bytes)
Inode-cache hash table entries: 131072 (order: 4, 1048576 bytes)
freeing bootmem node 0
freeing bootmem node 1
Memory: 1995968k/2097152k available (9280k kernel code, 101184k reserved, 1216k data, 7639k bss, 1984k init)
SLUB: Genslabs=17, HWalign=128, Order=0-3, MinObjects=0, CPUs=32, Nodes=16
Calibrating delay loop... 374.78 BogoMIPS (lpj=749568)
Mount-cache hash table entries: 4096
xics: map virq 16, hwirq 0x2
xics: unmask virq 16
-> map to hwirq 0x2
clockevent: decrementer mult[3023] shift[16] cpu[1]
Processor 1 found.
clockevent: decrementer mult[3023] shift[16] cpu[2]
Processor 2 found.
clockevent: decrementer mult[3023] shift[16] cpu[3]
Processor 3 found.
clockevent: decrementer mult[3023] shift[16] cpu[4]
Processor 4 found.
clockevent: decrementer mult[3023] shift[16] cpu[5]
Processor 5 found.
clockevent: decrementer mult[3023] shift[16] cpu[6]
Processor 6 found.
clockevent: decrementer mult[3023] shift[16] cpu[7]
Processor 7 found.
Brought up 8 CPUs
Node 0 CPUs: 0-7
Node 1 CPUs:
CPU0 attaching sched-domain:
domain 0: span 0-1 level SIBLING
groups: 0 1
domain 1: span 0-7 level CPU
groups: 0-1 2-3 4-5 6-7
domain 2: span 0-7 level NODE
groups: 0-7
CPU1 attaching sched-domain:
domain 0: span 0-1 level SIBLING
groups: 1 0
domain 1: span 0-7 level CPU
groups: 0-1 2-3 4-5 6-7
domain 2: span 0-7 level NODE
groups: 0-7
CPU2 attaching sched-domain:
domain 0: span 2-3 level SIBLING
groups: 2 3
domain 1: span 0-7 level CPU
groups: 2-3 4-5 6-7 0-1
domain 2: span 0-7 level NODE
groups: 0-7
CPU3 attaching sched-domain:
domain 0: span 2-3 level SIBLING
groups: 3 2
domain 1: span 0-7 level CPU
groups: 2-3 4-5 6-7 0-1
domain 2: span 0-7 level NODE
groups: 0-7
CPU4 attaching sched-domain:
domain 0: span 4-5 level SIBLING
groups: 4 5
domain 1: span 0-7 level CPU
groups: 4-5 6-7 0-1 2-3
domain 2: span 0-7 level NODE
groups: 0-7
CPU5 attaching sched-domain:
domain 0: span 4-5 level SIBLING
groups: 5 4
domain 1: span 0-7 level CPU
groups: 4-5 6-7 0-1 2-3
domain 2: span 0-7 level NODE
groups: 0-7
CPU6 attaching sched-domain:
domain 0: span 6-7 level SIBLING
groups: 6 7
domain 1: span 0-7 level CPU
groups: 6-7 0-1 2-3 4-5
domain 2: span 0-7 level NODE
groups: 0-7
CPU7 attaching sched-domain:
domain 0: span 6-7 level SIBLING
groups: 7 6
domain 1: span 0-7 level CPU
groups: 6-7 0-1 2-3 4-5
domain 2: span 0-7 level NODE
groups: 0-7
khelper used greatest stack depth: 10464 bytes left
net_namespace: 1280 bytes
NET: Registered protocol family 16
IBM eBus Device Driver
PCI: Probing PCI hardware
PCI: Probing PCI hardware done
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 16384 (order: 1, 131072 bytes)
TCP established hash table entries: 65536 (order: 4, 1048576 bytes)
TCP bind hash table entries: 65536 (order: 6, 4194304 bytes)
TCP: Hash tables configured (established 65536 bind 65536)
TCP reno registered
NET: Registered protocol family 1
xics: map virq 17, hwirq 0xa0000
xics: map virq 18, hwirq 0xa0002
IOMMU table initialized, virtual merging enabled
xics: map virq 20, hwirq 0xa0014
xics: map virq 19, hwirq 0x90001
xics: unmask virq 19
-> map to hwirq 0x90001
RTAS daemon started
rtasd: will sleep for 7500 milliseconds
rtasd: logging event
RTAS: event: 14, Type: Platform Error, Severity: 2
audit: initializing netlink socket (disabled)
type=2000 audit(1223873798.428:1): initialized
HugeTLB registered 16 MB page size, pre-allocated 0 pages
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
msgmni has been set to 3896
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
vio_register_driver: driver hvc_console registering
HVSI: registered 0 devices
Generic RTC Driver v1.07
Serial: 8250/16550 driver4 ports, IRQ sharing disabled
brd: module loaded
loop: module loaded
Intel(R) PRO/1000 Network Driver - version 7.3.20-k3-NAPI
Copyright (c) 1999-2006 Intel Corporation.
IBM eHEA ethernet device driver (Release EHEA_0092)
pcnet32.c:v1.35 21.Apr.2008 tsbogend@alpha.franken.de
e100: Intel(R) PRO/100 Network Driver, 3.5.23-k4-NAPI
e100: Copyright(c) 1999-2006 Intel Corporation
/home/benh/kernels/linux-test-powerpc/drivers/net/ibmveth.c: ibmveth: IBM i/pSeries Virtual Ethernet Driver 1.03
vio_register_driver: driver ibmveth registering
console [netcon0] enabled
netconsole: network logging started
Uniform Multi-Platform E-IDE driver
vio_register_driver: driver ibmvscsi registering
ibmvscsi 30000014: SRP_VERSION: 16.a
xics: unmask virq 20
-> map to hwirq 0xa0014
scsi0 : IBM POWER Virtual SCSI Adapter 1.5.8
ibmvscsi 30000014: partner initialization complete
ibmvscsi 30000014: sent SRP login
ibmvscsi 30000014: SRP_LOGIN succeeded
ibmvscsi 30000014: host srp version: 16.a, host partition 1-Diego-VIOS (1), OS 3, max io 262144
scsi 0:0:1:0: Direct-Access AIX VDASD 0001 PQ: 0 ANSI: 3
scsi 0:0:2:0: Direct-Access AIX VDASD 0001 PQ: 0 ANSI: 3
scsi 0:0:3:0: Direct-Access AIX VDASD 0001 PQ: 0 ANSI: 3
st: Version 20080504, fixed bufsize 32768, s/g segs 256
Driver 'st' needs updating - please use bus_type methods
Driver 'sd' needs updating - please use bus_type methods
sd 0:0:1:0: [sda] 20971520 512-byte hardware sectors (10737 MB)
sd 0:0:1:0: [sda] Write Protect is off
sd 0:0:1:0: [sda] Mode Sense: 17 00 00 08
sd 0:0:1:0: [sda] Cache data unavailable
sd 0:0:1:0: [sda] Assuming drive cache: write through
sd 0:0:1:0: [sda] 20971520 512-byte hardware sectors (10737 MB)
sd 0:0:1:0: [sda] Write Protect is off
sd 0:0:1:0: [sda] Mode Sense: 17 00 00 08
sd 0:0:1:0: [sda] Cache data unavailable
sd 0:0:1:0: [sda] Assuming drive cache: write through
sda: sda1 sda2 sda3
sd 0:0:1:0: [sda] Attached SCSI disk
sd 0:0:2:0: [sdb] 20971520 512-byte hardware sectors (10737 MB)
sd 0:0:2:0: [sdb] Write Protect is off
sd 0:0:2:0: [sdb] Mode Sense: 17 00 00 08
sd 0:0:2:0: [sdb] Cache data unavailable
sd 0:0:2:0: [sdb] Assuming drive cache: write through
sd 0:0:2:0: [sdb] 20971520 512-byte hardware sectors (10737 MB)
sd 0:0:2:0: [sdb] Write Protect is off
sd 0:0:2:0: [sdb] Mode Sense: 17 00 00 08
sd 0:0:2:0: [sdb] Cache data unavailable
sd 0:0:2:0: [sdb] Assuming drive cache: write through
sdb: sdb1
sd 0:0:2:0: [sdb] Attached SCSI disk
sd 0:0:3:0: [sdc] 20971520 512-byte hardware sectors (10737 MB)
sd 0:0:3:0: [sdc] Write Protect is off
sd 0:0:3:0: [sdc] Mode Sense: 17 00 00 08
sd 0:0:3:0: [sdc] Cache data unavailable
sd 0:0:3:0: [sdc] Assuming drive cache: write through
sd 0:0:3:0: [sdc] 20971520 512-byte hardware sectors (10737 MB)
sd 0:0:3:0: [sdc] Write Protect is off
sd 0:0:3:0: [sdc] Mode Sense: 17 00 00 08
sd 0:0:3:0: [sdc] Cache data unavailable
sd 0:0:3:0: [sdc] Assuming drive cache: write through
sdc: sdc1 sdc2
sd 0:0:3:0: [sdc] Attached SCSI disk
Driver 'sr' needs updating - please use bus_type methods
sd 0:0:1:0: Attached scsi generic sg0 type 0
sd 0:0:2:0: Attached scsi generic sg1 type 0
sd 0:0:3:0: Attached scsi generic sg2 type 0
ohci_hcd: 2006 August 04 USB 1.1 'Open' Host Controller (OHCI) Driver
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
mice: PS/2 mouse device common for all mice
md: linear personality registered for level -1
md: raid0 personality registered for level 0
md: raid1 personality registered for level 1
device-mapper: ioctl: 4.14.0-ioctl (2008-04-23) initialised: dm-devel@redhat.com
usbcore: registered new interface driver hiddev
usbcore: registered new interface driver usbhid
usbhid: v2.6:USB HID core driver
oprofile: using ppc64/power5 performance monitoring.
IPv4 over IPv4 tunneling driver
TCP cubic registered
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
registered taskstats version 1
md: Autodetecting RAID arrays.
md: Scanned 0 and added 0 devices.
md: autorun ...
md: ... autorun DONE.
EXT3-fs: INFO: recovery required on readonly filesystem.
EXT3-fs: write access will be enabled during recovery.
kjournald starting. Commit interval 5 seconds
EXT3-fs: recovery complete.
EXT3-fs: mounted filesystem with ordered data mode.
VFS: Mounted root (ext3 filesystem) readonly.
Freeing unused kernel memory: 1984k freed
xics: unmask virq 17
-> map to hwirq 0xa0000
xics: mask virq 17
xics: unmask virq 17
-> map to hwirq 0xa0000
runlevel used greatest stack depth: 8816 bytes left
grep used greatest stack depth: 8160 bytes left
mount used greatest stack depth: 7344 bytes left
ckbcomp used greatest stack depth: 5920 bytes left
EXT3 FS on sdb1, internal journal
kjournald starting. Commit interval 5 seconds
EXT3 FS on sdc2, internal journal
EXT3-fs: mounted filesystem with ordered data mode.
Adding 1015680k swap on /dev/mapper/VolGroup00-LogVol01. Priority:-1 extents:1 across:1015680k
xics: unmask virq 18
-> map to hwirq 0xa0002
warning: `dhclient3' uses 32-bit capabilities (legacy support in use)
=========================================================
[ INFO: possible irq lock inversion dependency detected ]
2.6.27-rc5-test #22
---------------------------------------------------------
swapper/0 just changed the state of lock:
(&hp->lock){+...}, at: [<c0000000002e61e0>] .hvc_poll+0x50/0x2f0
but this lock took another, hard-irq-unsafe lock in the past:
(proc_subdir_lock){--..}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this:
no locks held by swapper/0.
the first lock's dependencies:
-> (&hp->lock){+...} ops: 1563368095744 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000002e5ea0>] .hvc_get_by_index+0x54/0x110
[<c0000000002e5f90>] .hvc_open+0x34/0x14c
[<c0000000002cca74>] .tty_open+0x250/0x3b4
[<c0000000000e7b9c>] .chrdev_open+0x1c4/0x204
[<c0000000000e1f98>] .__dentry_open+0x190/0x308
[<c0000000000f2504>] .do_filp_open+0x400/0x84c
[<c0000000000e1d18>] .do_sys_open+0x80/0x140
[<c00000000000920c>] .init_post+0x4c/0x108
[<c000000000720d28>] .kernel_init+0x2a8/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
in-hardirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000002e61e0>] .hvc_poll+0x50/0x2f0
[<c0000000002e66d8>] .hvc_handle_interrupt+0x14/0x3c
[<c00000000009f140>] .handle_IRQ_event+0x50/0xc8
[<c0000000000a15e4>] .handle_fasteoi_irq+0x120/0x1bc
[<c000000000025e00>] .call_handle_irq+0x1c/0x2c
[<c00000000000d118>] .do_IRQ+0x128/0x1fc
[<c000000000004804>] hardware_interrupt_entry+0x1c/0x98
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004e7c6c>] .rest_init+0x7c/0x94
[<c000000000720a58>] .start_kernel+0x48c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000001209a88>] __key.17726+0x0/0x8
-> (&tty->buf.lock){....} ops: 146028888064 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000002c987c>] .tty_buffer_request_room+0x40/0x198
[<c0000000002e6260>] .hvc_poll+0xd0/0x2f0
[<c0000000002e6504>] .khvcd+0x84/0x18c
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
}
... key at: [<c0000000011f7150>] __key.20956+0x0/0x8
-> (&zone->lock){.+..} ops: 167834437025792 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c0000000000ac73c>] .free_pages_bulk+0x60/0x318
[<c0000000000ad924>] .free_hot_cold_page+0x20c/0x278
[<c00000000073b684>] .free_all_bootmem_core+0x12c/0x240
[<c000000000731fe4>] .mem_init+0x9c/0x218
[<c000000000720968>] .start_kernel+0x39c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c0000000000adbc0>] .__free_pages_ok+0x1a4/0x414
[<c0000000000d9fbc>] .__free_slab+0x140/0x16c
[<c0000000000dbefc>] .kmem_cache_free+0xec/0x148
[<c00000000000f918>] .free_thread_info+0x24/0x3c
[<c000000000054e6c>] .free_task+0x30/0x60
[<c00000000005949c>] .delayed_put_task_struct+0x38/0x4c
[<c0000000000a2a30>] .__rcu_process_callbacks+0x1e4/0x2bc
[<c0000000000a2b44>] .rcu_process_callbacks+0x3c/0x64
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004ed9cc>] .start_secondary+0x350/0x388
[<c000000000008264>] .start_secondary_prolog+0x10/0x14
}
... key at: [<c00000000114c200>] __key.26488+0x0/0x8
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c0000000000ac498>] .rmqueue_bulk+0x50/0xe0
[<c0000000000ae2c0>] .get_page_from_freelist+0x2d4/0x758
[<c0000000000aef30>] .__alloc_pages_internal+0x158/0x4dc
[<c0000000000d2a00>] .alloc_pages_current+0xcc/0xf4
[<c0000000000dafe4>] .new_slab+0x88/0x32c
[<c0000000000db5dc>] .__slab_alloc+0x29c/0x51c
[<c0000000000ddcec>] .__kmalloc+0xc4/0x160
[<c0000000002c9924>] .tty_buffer_request_room+0xe8/0x198
[<c0000000002e6260>] .hvc_poll+0xd0/0x2f0
[<c0000000002e6504>] .khvcd+0x84/0x18c
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000002c987c>] .tty_buffer_request_room+0x40/0x198
[<c0000000002e6260>] .hvc_poll+0xd0/0x2f0
[<c0000000002e6504>] .khvcd+0x84/0x18c
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
-> (&irq_desc_lock_class){++..} ops: 18859201396736 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000000a109c>] .set_irq_chip+0x60/0xac
[<c0000000000a115c>] .set_irq_chip_and_handler+0x20/0x48
[<c00000000003be54>] .xics_host_map+0x6c/0x90
[<c00000000000bf1c>] .irq_setup_virq+0x6c/0xa8
[<c00000000000c610>] .irq_create_mapping+0x108/0x13c
[<c000000000736410>] .smp_xics_probe+0x24/0xb4
[<c00000000073055c>] .smp_prepare_cpus+0x98/0x188
[<c000000000720ae4>] .kernel_init+0x64/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
in-hardirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c0000000000a1500>] .handle_fasteoi_irq+0x3c/0x1bc
[<c000000000025e00>] .call_handle_irq+0x1c/0x2c
[<c00000000000d118>] .do_IRQ+0x128/0x1fc
[<c000000000004804>] hardware_interrupt_entry+0x1c/0x98
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004e7c6c>] .rest_init+0x7c/0x94
[<c000000000720a58>] .start_kernel+0x48c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c0000000000a1500>] .handle_fasteoi_irq+0x3c/0x1bc
[<c000000000025e00>] .call_handle_irq+0x1c/0x2c
[<c00000000000d118>] .do_IRQ+0x128/0x1fc
[<c000000000004804>] hardware_interrupt_entry+0x1c/0x98
[<c00000000005d988>] .__do_softirq+0x8c/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004e7c6c>] .rest_init+0x7c/0x94
[<c000000000720a58>] .start_kernel+0x48c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c0000000011480a8>] irq_desc_lock_class+0x0/0x8
-> (old_style_spin_init){....} ops: 63750199574528 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c00000000001ccf8>] .rtas_call+0x80/0x288
[<c000000000038fc8>] .pSeries_cmo_feature_init+0x84/0x290
[<c00000000073599c>] .pSeries_init_early+0x64/0x8c
[<c000000000729754>] .setup_system+0x20c/0x3b0
[<c000000000008358>] .start_here_common+0xc/0x34
}
... key at: [<c000000000932160>] rtas+0x30/0xb0
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c00000000001ccf8>] .rtas_call+0x80/0x288
[<c00000000003c064>] .xics_unmask_irq+0x90/0x114
[<c00000000003c0f8>] .xics_startup+0x10/0x24
[<c0000000000a0098>] .setup_irq+0x228/0x35c
[<c0000000000a0290>] .request_irq+0xc4/0x114
[<c00000000003a5ec>] .request_ras_irqs+0x184/0x1fc
[<c000000000735be4>] .init_ras_IRQ+0x94/0xb8
[<c000000000009044>] .do_one_initcall+0x8c/0x1c8
[<c000000000720cd4>] .kernel_init+0x254/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c00000000009fba0>] .free_irq+0x6c/0x18c
[<c0000000002e6634>] .notifier_del_irq+0x28/0x48
[<c0000000002e5ddc>] .hvc_close+0xa0/0x110
[<c0000000002cc328>] .release_dev+0x244/0x580
[<c0000000002cc688>] .tty_release+0x24/0x44
[<c0000000000e5384>] .__fput+0xf8/0x1dc
[<c0000000000e1bec>] .filp_close+0xb4/0xdc
[<c0000000000e33a4>] .sys_close+0xac/0x100
[<c0000000000084d4>] syscall_exit+0x0/0x40
-> (proc_subdir_lock){--..} ops: 15307263442944 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139144>] .xlate_proc_name+0x50/0xf8
[<c0000000001395b4>] .__proc_create+0x6c/0x15c
[<c000000000139a54>] .create_proc_entry+0x6c/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
softirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139144>] .xlate_proc_name+0x50/0xf8
[<c0000000001395b4>] .__proc_create+0x6c/0x15c
[<c000000000139a54>] .create_proc_entry+0x6c/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
hardirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139144>] .xlate_proc_name+0x50/0xf8
[<c0000000001395b4>] .__proc_create+0x6c/0x15c
[<c000000000139a54>] .create_proc_entry+0x6c/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000000939018>] proc_subdir_lock+0x18/0x38
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139144>] .xlate_proc_name+0x50/0xf8
[<c0000000001392f4>] .remove_proc_entry+0x44/0x298
[<c0000000000a1e74>] .unregister_handler_proc+0x40/0x58
[<c00000000009fc58>] .free_irq+0x124/0x18c
[<c0000000002e6634>] .notifier_del_irq+0x28/0x48
[<c0000000002e5ddc>] .hvc_close+0xa0/0x110
[<c0000000002cc328>] .release_dev+0x244/0x580
[<c0000000002cc688>] .tty_release+0x24/0x44
[<c0000000000e5384>] .__fput+0xf8/0x1dc
[<c0000000000e1bec>] .filp_close+0xb4/0xdc
[<c0000000000e33a4>] .sys_close+0xac/0x100
[<c0000000000084d4>] syscall_exit+0x0/0x40
-> (&ent->pde_unload_lock){--..} ops: 178743653957632 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139384>] .remove_proc_entry+0xd4/0x298
[<c0000000000a1e74>] .unregister_handler_proc+0x40/0x58
[<c00000000009fc58>] .free_irq+0x124/0x18c
[<c0000000002e6634>] .notifier_del_irq+0x28/0x48
[<c0000000002e5ddc>] .hvc_close+0xa0/0x110
[<c0000000002cc328>] .release_dev+0x244/0x580
[<c0000000002cc688>] .tty_release+0x24/0x44
[<c0000000000e5384>] .__fput+0xf8/0x1dc
[<c0000000000e1bec>] .filp_close+0xb4/0xdc
[<c0000000000e33a4>] .sys_close+0xac/0x100
[<c0000000000084d4>] syscall_exit+0x0/0x40
softirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000133994>] .proc_reg_open+0x68/0x1a4
[<c0000000000e1f98>] .__dentry_open+0x190/0x308
[<c0000000000f2504>] .do_filp_open+0x400/0x84c
[<c0000000000e1d18>] .do_sys_open+0x80/0x140
[<c000000000122b80>] .compat_sys_open+0x24/0x38
[<c0000000000084d4>] syscall_exit+0x0/0x40
hardirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000133994>] .proc_reg_open+0x68/0x1a4
[<c0000000000e1f98>] .__dentry_open+0x190/0x308
[<c0000000000f2504>] .do_filp_open+0x400/0x84c
[<c0000000000e1d18>] .do_sys_open+0x80/0x140
[<c000000000122b80>] .compat_sys_open+0x24/0x38
[<c0000000000084d4>] syscall_exit+0x0/0x40
}
... key at: [<c00000000114f99c>] __key.16461+0x0/0xc
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139384>] .remove_proc_entry+0xd4/0x298
[<c0000000000a1e74>] .unregister_handler_proc+0x40/0x58
[<c00000000009fc58>] .free_irq+0x124/0x18c
[<c0000000002e6634>] .notifier_del_irq+0x28/0x48
[<c0000000002e5ddc>] .hvc_close+0xa0/0x110
[<c0000000002cc328>] .release_dev+0x244/0x580
[<c0000000002cc688>] .tty_release+0x24/0x44
[<c0000000000e5384>] .__fput+0xf8/0x1dc
[<c0000000000e1bec>] .filp_close+0xb4/0xdc
[<c0000000000e33a4>] .sys_close+0xac/0x100
[<c0000000000084d4>] syscall_exit+0x0/0x40
-> (proc_inum_lock){--..} ops: 3435973836800 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139754>] .proc_register+0x64/0x224
[<c000000000139a68>] .create_proc_entry+0x80/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
softirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139754>] .proc_register+0x64/0x224
[<c000000000139a68>] .create_proc_entry+0x80/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
hardirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139754>] .proc_register+0x64/0x224
[<c000000000139a68>] .create_proc_entry+0x80/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000000939050>] proc_inum_lock+0x18/0x38
-> (proc_inum_ida.lock){....} ops: 6932077215744 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c000000000252fd0>] .idr_pre_get+0x5c/0xc0
[<c00000000025305c>] .ida_pre_get+0x28/0xa8
[<c000000000139740>] .proc_register+0x50/0x224
[<c000000000139a68>] .create_proc_entry+0x80/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c0000000009390a0>] proc_inum_ida+0x30/0x58
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c000000000252768>] .get_from_free_list+0x28/0x84
[<c0000000002528f4>] .idr_get_empty_slot+0x5c/0x2ec
[<c000000000252c04>] .ida_get_new_above+0x80/0x28c
[<c000000000139764>] .proc_register+0x74/0x224
[<c000000000139a68>] .create_proc_entry+0x80/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139238>] .free_proc_entry+0x4c/0xc4
[<c000000000139518>] .remove_proc_entry+0x268/0x298
[<c0000000000a1e74>] .unregister_handler_proc+0x40/0x58
[<c00000000009fc58>] .free_irq+0x124/0x18c
[<c0000000002e6634>] .notifier_del_irq+0x28/0x48
[<c0000000002e5ddc>] .hvc_close+0xa0/0x110
[<c0000000002cc328>] .release_dev+0x244/0x580
[<c0000000002cc688>] .tty_release+0x24/0x44
[<c0000000000e5384>] .__fput+0xf8/0x1dc
[<c0000000000e1bec>] .filp_close+0xb4/0xdc
[<c0000000000e33a4>] .sys_close+0xac/0x100
[<c0000000000084d4>] syscall_exit+0x0/0x40
-> (&q->lock){.+..} ops: 265274360070144 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e76d0>] ._spin_lock_irq+0x58/0xb4
[<c0000000004e32f4>] .wait_for_common+0x48/0x1d4
[<c000000000071c50>] .kthread_create+0xb8/0x110
[<c0000000004eb0b0>] .migration_call+0xc8/0x660
[<c000000000736d8c>] .migration_init+0x34/0x90
[<c000000000009044>] .do_one_initcall+0x8c/0x1c8
[<c000000000720b00>] .kernel_init+0x80/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c00000000004862c>] .complete+0x28/0x80
[<c00000000006ec0c>] .wakeme_after_rcu+0x14/0x28
[<c0000000000a2a30>] .__rcu_process_callbacks+0x1e4/0x2bc
[<c0000000000a2b44>] .rcu_process_callbacks+0x3c/0x64
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004e7c6c>] .rest_init+0x7c/0x94
[<c000000000720a58>] .start_kernel+0x48c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000000b17968>] __key.14384+0x0/0x8
-> (&rq->lock){++..} ops: 19113192877719552 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c000000000048404>] .rq_attach_root+0x30/0x1a8
[<c0000000007371e8>] .sched_init+0x334/0x408
[<c0000000007207a8>] .start_kernel+0x1dc/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
in-hardirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000053fac>] .scheduler_tick+0x48/0x154
[<c0000000000643f0>] .update_process_times+0x60/0x8c
[<c00000000007c7c4>] .tick_periodic+0x9c/0xc4
[<c00000000007c824>] .tick_handle_periodic+0x38/0xbc
[<c000000000022b40>] .timer_interrupt+0xac/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c00000000025eb00>] .dotest+0x4dc/0x544
[<c00000000026c8f4>] .locking_selftest+0x124/0x17ec
[<c0000000007208f8>] .start_kernel+0x32c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c000000000053854>] .tg_shares_up+0x108/0x20c
[<c000000000048384>] .walk_tg_tree+0xf0/0x140
[<c00000000004dda0>] .run_rebalance_domains+0x1ac/0x5fc
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004e7c6c>] .rest_init+0x7c/0x94
[<c000000000720a58>] .start_kernel+0x48c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000000af04e8>] __key.39338+0x0/0x8
-> (&vec->lock){++..} ops: 11192684773376 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000000a4c18>] .cpupri_set+0x12c/0x1f0
[<c00000000004b3d4>] .rq_online_rt+0xac/0xc4
[<c000000000046c38>] .set_rq_online+0xa8/0xd4
[<c000000000048548>] .rq_attach_root+0x174/0x1a8
[<c0000000007371e8>] .sched_init+0x334/0x408
[<c0000000007207a8>] .start_kernel+0x1dc/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
in-hardirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000000a4b64>] .cpupri_set+0x78/0x1f0
[<c00000000004c0f8>] .__enqueue_rt_entity+0x114/0x1d0
[<c00000000004c25c>] .enqueue_task_rt+0x4c/0x84
[<c0000000000472d0>] .enqueue_task+0x84/0xac
[<c000000000047328>] .activate_task+0x30/0x50
[<c00000000004dafc>] .try_to_wake_up+0x1a0/0x27c
[<c00000000009eabc>] .softlockup_tick+0x130/0x214
[<c000000000064064>] .run_local_timers+0x24/0x38
[<c0000000000643c8>] .update_process_times+0x38/0x8c
[<c00000000007c7c4>] .tick_periodic+0x9c/0xc4
[<c00000000007c824>] .tick_handle_periodic+0x38/0xbc
[<c000000000022b40>] .timer_interrupt+0xac/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004ed9cc>] .start_secondary+0x350/0x388
[<c000000000008264>] .start_secondary_prolog+0x10/0x14
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000000a4b64>] .cpupri_set+0x78/0x1f0
[<c00000000004c0f8>] .__enqueue_rt_entity+0x114/0x1d0
[<c00000000004c25c>] .enqueue_task_rt+0x4c/0x84
[<c0000000000472d0>] .enqueue_task+0x84/0xac
[<c000000000047328>] .activate_task+0x30/0x50
[<c00000000004dafc>] .try_to_wake_up+0x1a0/0x27c
[<c00000000004e018>] .run_rebalance_domains+0x424/0x5fc
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004ed9cc>] .start_secondary+0x350/0x388
[<c000000000008264>] .start_secondary_prolog+0x10/0x14
}
... key at: [<c0000000011480f0>] __key.11749+0x0/0x10
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000000a4c18>] .cpupri_set+0x12c/0x1f0
[<c00000000004b3d4>] .rq_online_rt+0xac/0xc4
[<c000000000046c38>] .set_rq_online+0xa8/0xd4
[<c000000000048548>] .rq_attach_root+0x174/0x1a8
[<c0000000007371e8>] .sched_init+0x334/0x408
[<c0000000007207a8>] .start_kernel+0x1dc/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
-> (&rt_b->rt_runtime_lock){++..} ops: 210453397504 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000004c148>] .__enqueue_rt_entity+0x164/0x1d0
[<c00000000004c25c>] .enqueue_task_rt+0x4c/0x84
[<c0000000000472d0>] .enqueue_task+0x84/0xac
[<c000000000047328>] .activate_task+0x30/0x50
[<c00000000004dafc>] .try_to_wake_up+0x1a0/0x27c
[<c0000000004eb14c>] .migration_call+0x164/0x660
[<c000000000736db8>] .migration_init+0x60/0x90
[<c000000000009044>] .do_one_initcall+0x8c/0x1c8
[<c000000000720b00>] .kernel_init+0x80/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
in-hardirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000004c148>] .__enqueue_rt_entity+0x164/0x1d0
[<c00000000004c25c>] .enqueue_task_rt+0x4c/0x84
[<c0000000000472d0>] .enqueue_task+0x84/0xac
[<c000000000047328>] .activate_task+0x30/0x50
[<c00000000004dafc>] .try_to_wake_up+0x1a0/0x27c
[<c00000000009eabc>] .softlockup_tick+0x130/0x214
[<c000000000064064>] .run_local_timers+0x24/0x38
[<c0000000000643c8>] .update_process_times+0x38/0x8c
[<c00000000007c7c4>] .tick_periodic+0x9c/0xc4
[<c00000000007c824>] .tick_handle_periodic+0x38/0xbc
[<c000000000022b40>] .timer_interrupt+0xac/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004ed9cc>] .start_secondary+0x350/0x388
[<c000000000008264>] .start_secondary_prolog+0x10/0x14
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000004c148>] .__enqueue_rt_entity+0x164/0x1d0
[<c00000000004c25c>] .enqueue_task_rt+0x4c/0x84
[<c0000000000472d0>] .enqueue_task+0x84/0xac
[<c000000000047328>] .activate_task+0x30/0x50
[<c00000000004dafc>] .try_to_wake_up+0x1a0/0x27c
[<c00000000004e018>] .run_rebalance_domains+0x424/0x5fc
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004ed9cc>] .start_secondary+0x350/0x388
[<c000000000008264>] .start_secondary_prolog+0x10/0x14
}
... key at: [<c000000000af04e0>] __key.31617+0x0/0x8
-> (&cpu_base->lock){++..} ops: 700504871010304 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e76d0>] ._spin_lock_irq+0x58/0xb4
[<c000000000075928>] .hrtimer_run_pending+0x3c/0x10c
[<c000000000063a34>] .run_timer_softirq+0x54/0x268
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c00000000025eb00>] .dotest+0x4dc/0x544
[<c00000000026c8f4>] .locking_selftest+0x124/0x17ec
[<c0000000007208f8>] .start_kernel+0x32c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
in-hardirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000007502c>] .hrtimer_run_queues+0x178/0x318
[<c000000000064050>] .run_local_timers+0x10/0x38
[<c0000000000643c8>] .update_process_times+0x38/0x8c
[<c00000000007c7c4>] .tick_periodic+0x9c/0xc4
[<c00000000007c824>] .tick_handle_periodic+0x38/0xbc
[<c000000000022b40>] .timer_interrupt+0xac/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c0000000004e6e7c>] ._spin_unlock_irqrestore+0x60/0x88
[<c00000000001ce64>] .rtas_call+0x1ec/0x288
[<c0000000004ef0f4>] .smp_pSeries_kick_cpu+0xc0/0x10c
[<c0000000004ea98c>] .__cpu_up+0x114/0x254
[<c0000000004eb950>] .cpu_up+0x11c/0x1f0
[<c000000000720bdc>] .kernel_init+0x15c/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e76d0>] ._spin_lock_irq+0x58/0xb4
[<c000000000075928>] .hrtimer_run_pending+0x3c/0x10c
[<c000000000063a34>] .run_timer_softirq+0x54/0x268
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c00000000025eb00>] .dotest+0x4dc/0x544
[<c00000000026c8f4>] .locking_selftest+0x124/0x17ec
[<c0000000007208f8>] .start_kernel+0x32c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000000b179a0>] __key.18246+0x0/0x8
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c0000000000752ac>] .lock_hrtimer_base+0x34/0x8c
[<c0000000000754d0>] .hrtimer_start+0x4c/0x1b0
[<c00000000004c180>] .__enqueue_rt_entity+0x19c/0x1d0
[<c00000000004c25c>] .enqueue_task_rt+0x4c/0x84
[<c0000000000472d0>] .enqueue_task+0x84/0xac
[<c000000000047328>] .activate_task+0x30/0x50
[<c00000000004dafc>] .try_to_wake_up+0x1a0/0x27c
[<c0000000004eb14c>] .migration_call+0x164/0x660
[<c000000000736db8>] .migration_init+0x60/0x90
[<c000000000009044>] .do_one_initcall+0x8c/0x1c8
[<c000000000720b00>] .kernel_init+0x80/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
-> (&rt_rq->rt_runtime_lock){+...} ops: 6090263625728 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000004bc28>] .update_curr_rt+0xac/0x144
[<c00000000004c1d4>] .dequeue_task_rt+0x20/0x5c
[<c0000000000471d0>] .dequeue_task+0xdc/0x108
[<c00000000004722c>] .deactivate_task+0x30/0x50
[<c0000000004e36f0>] .schedule+0x1b8/0x804
[<c000000000051d68>] .migration_thread+0x230/0x324
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
in-hardirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000004bec0>] .sched_rt_period_timer+0xd4/0x1f8
[<c0000000000750d0>] .hrtimer_run_queues+0x21c/0x318
[<c000000000064050>] .run_local_timers+0x10/0x38
[<c0000000000643c8>] .update_process_times+0x38/0x8c
[<c00000000007c7c4>] .tick_periodic+0x9c/0xc4
[<c00000000007c824>] .tick_handle_periodic+0x38/0xbc
[<c000000000022b40>] .timer_interrupt+0xac/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004e7c6c>] .rest_init+0x7c/0x94
[<c000000000720a58>] .start_kernel+0x48c/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000000af04f0>] __key.39293+0x0/0x8
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000049fc4>] .__enable_runtime+0x60/0xb0
[<c00000000004b3c0>] .rq_online_rt+0x98/0xc4
[<c000000000046c38>] .set_rq_online+0xa8/0xd4
[<c0000000004eb1b0>] .migration_call+0x1c8/0x660
[<c000000000076a14>] .notifier_call_chain+0x68/0xdc
[<c0000000004eb9bc>] .cpu_up+0x188/0x1f0
[<c000000000720bdc>] .kernel_init+0x15c/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000004c148>] .__enqueue_rt_entity+0x164/0x1d0
[<c00000000004c25c>] .enqueue_task_rt+0x4c/0x84
[<c0000000000472d0>] .enqueue_task+0x84/0xac
[<c000000000047328>] .activate_task+0x30/0x50
[<c00000000004dafc>] .try_to_wake_up+0x1a0/0x27c
[<c0000000004eb14c>] .migration_call+0x164/0x660
[<c000000000736db8>] .migration_init+0x60/0x90
[<c000000000009044>] .do_one_initcall+0x8c/0x1c8
[<c000000000720b00>] .kernel_init+0x80/0x2cc
[<c000000000025f98>] .kernel_thread+0x54/0x70
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c00000000004bc28>] .update_curr_rt+0xac/0x144
[<c00000000004c1d4>] .dequeue_task_rt+0x20/0x5c
[<c0000000000471d0>] .dequeue_task+0xdc/0x108
[<c00000000004722c>] .deactivate_task+0x30/0x50
[<c0000000004e36f0>] .schedule+0x1b8/0x804
[<c000000000051d68>] .migration_thread+0x230/0x324
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
-> (&rq->lock/1){.+..} ops: 5330054414336 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e709c>] ._spin_lock_nested+0x44/0xa0
[<c00000000004c450>] .double_rq_lock+0x78/0xc8
[<c00000000004c548>] .__migrate_task+0xa8/0x194
[<c000000000051db0>] .migration_thread+0x278/0x324
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
in-softirq-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e709c>] ._spin_lock_nested+0x44/0xa0
[<c00000000004c450>] .double_rq_lock+0x78/0xc8
[<c00000000004de30>] .run_rebalance_domains+0x23c/0x5fc
[<c00000000005d9c4>] .__do_softirq+0xc8/0x198
[<c000000000025dd4>] .call_do_softirq+0x14/0x24
[<c00000000000caac>] .do_softirq+0x94/0x114
[<c00000000005db58>] .irq_exit+0x70/0x88
[<c000000000022b68>] .timer_interrupt+0xd4/0x100
[<c000000000003704>] decrementer_common+0x104/0x180
[<c000000000011ffc>] .cpu_idle+0x124/0x1f8
[<c0000000004ed9cc>] .start_secondary+0x350/0x388
[<c000000000008264>] .start_secondary_prolog+0x10/0x14
}
... key at: [<c000000000af04e9>] __key.39338+0x1/0x8
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e709c>] ._spin_lock_nested+0x44/0xa0
[<c00000000004c450>] .double_rq_lock+0x78/0xc8
[<c00000000004c548>] .__migrate_task+0xa8/0x194
[<c000000000051db0>] .migration_thread+0x278/0x324
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000048a00>] .task_rq_lock+0x70/0xd4
[<c00000000004da30>] .try_to_wake_up+0xd4/0x27c
[<c000000000046a04>] .__wake_up_common+0x6c/0xe0
[<c000000000048658>] .complete+0x54/0x80
[<c000000000071ce0>] .kthread+0x38/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
... acquired at:
[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e7614>] ._spin_lock_irqsave+0x5c/0xc0
[<c000000000048744>] .__wake_up+0x34/0x88
[<c0000000002c9168>] .tty_wakeup+0x88/0xa4
[<c0000000002e6400>] .hvc_poll+0x270/0x2f0
[<c0000000002e6504>] .khvcd+0x84/0x18c
[<c000000000071d20>] .kthread+0x78/0xc4
[<c000000000025f98>] .kernel_thread+0x54/0x70
the second lock's dependencies:
-> (proc_subdir_lock){--..} ops: 15307263442944 {
initial-use at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139144>] .xlate_proc_name+0x50/0xf8
[<c0000000001395b4>] .__proc_create+0x6c/0x15c
[<c000000000139a54>] .create_proc_entry+0x6c/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
softirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139144>] .xlate_proc_name+0x50/0xf8
[<c0000000001395b4>] .__proc_create+0x6c/0x15c
[<c000000000139a54>] .create_proc_entry+0x6c/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
hardirq-on-W at:
[<c000000000083464>] .lock_acquire+0xa4/0xec
[<c0000000004e713c>] ._spin_lock+0x44/0xa0
[<c000000000139144>] .xlate_proc_name+0x50/0xf8
[<c0000000001395b4>] .__proc_create+0x6c/0x15c
[<c000000000139a54>] .create_proc_entry+0x6c/0xb0
[<c00000000073f9d0>] .proc_misc_init+0x3c/0x2f0
[<c00000000073f858>] .proc_root_init+0x78/0x104
[<c000000000720a40>] .start_kernel+0x474/0x4b4
[<c000000000008368>] .start_here_common+0x1c/0x34
}
... key at: [<c000000000939018>] proc_subdir_lock+0x18/0x38
stack backtrace:
Call Trace:
[c00000000fffb890] [c00000000000fa14] .show_stack+0x78/0x17c (unreliable)
[c00000000fffb940] [c00000000007ee54] .print_irq_inversion_bug+0x1a4/0x1d4
[c00000000fffb9e0] [c000000000080a80] .mark_lock+0x320/0xa1c
[c00000000fffba80] [c00000000008310c] .__lock_acquire+0x638/0x8ec
[c00000000fffbb70] [c000000000083464] .lock_acquire+0xa4/0xec
[c00000000fffbc30] [c0000000004e7614] ._spin_lock_irqsave+0x5c/0xc0
[c00000000fffbcd0] [c0000000002e61e0] .hvc_poll+0x50/0x2f0
[c00000000fffbdd0] [c0000000002e66d8] .hvc_handle_interrupt+0x14/0x3c
[c00000000fffbe50] [c00000000009f140] .handle_IRQ_event+0x50/0xc8
[c00000000fffbef0] [c0000000000a15e4] .handle_fasteoi_irq+0x120/0x1bc
[c00000000fffbf90] [c000000000025e00] .call_handle_irq+0x1c/0x2c
[c000000000a43a40] [c00000000000d118] .do_IRQ+0x128/0x1fc
[c000000000a43ae0] [c000000000004804] hardware_interrupt_entry+0x1c/0x98
--- Exception: 501 at .raw_local_irq_restore+0x3c/0x40
LR = .cpu_idle+0x130/0x1f8
[c000000000a43dd0] [c000000000011ffc] .cpu_idle+0x124/0x1f8 (unreliable)
[c000000000a43e60] [c0000000004e7c6c] .rest_init+0x7c/0x94
[c000000000a43ee0] [c000000000720a58] .start_kernel+0x48c/0x4b4
[c000000000a43f90] [c000000000008368] .start_here_common+0x1c/0x34
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-10-13 5:16 ` Benjamin Herrenschmidt
@ 2008-10-13 7:51 ` Christian Borntraeger
2008-10-13 8:36 ` Benjamin Herrenschmidt
2008-10-14 0:38 ` Benjamin Herrenschmidt
0 siblings, 2 replies; 24+ messages in thread
From: Christian Borntraeger @ 2008-10-13 7:51 UTC (permalink / raw)
To: benh
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
Am Montag, 13. Oktober 2008 schrieb Benjamin Herrenschmidt:
> =A0 ... key =A0 =A0 =A0at: [<c000000000939018>] proc_subdir_lock+0x18/0x38
> =A0... acquired at:
> =A0 =A0[<c0000000000832e8>] .__lock_acquire+0x814/0x8ec
> =A0 =A0[<c000000000083464>] .lock_acquire+0xa4/0xec
> =A0 =A0[<c0000000004e713c>] ._spin_lock+0x44/0xa0
> =A0 =A0[<c000000000139144>] .xlate_proc_name+0x50/0xf8
> =A0 =A0[<c0000000001392f4>] .remove_proc_entry+0x44/0x298
> =A0 =A0[<c0000000000a1e74>] .unregister_handler_proc+0x40/0x58
> =A0 =A0[<c00000000009fc58>] .free_irq+0x124/0x18c
> =A0 =A0[<c0000000002e6634>] .notifier_del_irq+0x28/0x48
> =A0 =A0[<c0000000002e5ddc>] .hvc_close+0xa0/0x110
> =A0 =A0[<c0000000002cc328>] .release_dev+0x244/0x580
> =A0 =A0[<c0000000002cc688>] .tty_release+0x24/0x44
> =A0 =A0[<c0000000000e5384>] .__fput+0xf8/0x1dc
> =A0 =A0[<c0000000000e1bec>] .filp_close+0xb4/0xdc
> =A0 =A0[<c0000000000e33a4>] .sys_close+0xac/0x100
> =A0 =A0[<c0000000000084d4>] syscall_exit+0x0/0x40
Hmmm.=20
Can you try if this patch fixes the lockdep trace?
This would be analog to
commit b1b135c8d619cb2c7045d6ee4e48375882518bb5
Author: Christian Borntraeger <borntraeger@de.ibm.com>
Date: Thu Aug 7 09:18:34 2008 +0200
fix spinlock recursion in hvc_console
commit 611e097d7707741a336a0677d9d69bec40f29f3d
Author: Christian Borntraeger <borntraeger@de.ibm.com>
hvc_console: rework setup to replace irq functions with callbacks
introduced a spinlock recursion problem.
Signed-off-by: Christian Borntraeger<borntraeger@de.ibm.com>
=2D--
drivers/char/hvc_console.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
Index: linux-2.6/drivers/char/hvc_console.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2D-- linux-2.6.orig/drivers/char/hvc_console.c
+++ linux-2.6/drivers/char/hvc_console.c
@@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct=20
spin_lock_irqsave(&hp->lock, flags);
=20
if (--hp->count =3D=3D 0) {
=2D if (hp->ops->notifier_del)
=2D hp->ops->notifier_del(hp, hp->data);
=2D
/* We are done with the tty pointer now. */
hp->tty =3D NULL;
spin_unlock_irqrestore(&hp->lock, flags);
=20
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
+
/*
* Chain calls chars_in_buffer() and returns immediately if
* there is no buffered data otherwise sleeps on a wait queue
@@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct
hp->n_outbuf =3D 0;
hp->tty =3D NULL;
=20
+ spin_unlock_irqrestore(&hp->lock, flags);
+
if (hp->ops->notifier_del)
hp->ops->notifier_del(hp, hp->data);
=20
=2D spin_unlock_irqrestore(&hp->lock, flags);
=2D
while(temp_open_count) {
--temp_open_count;
kref_put(&hp->kref, destroy_hvc_struct);
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-10-13 7:51 ` Christian Borntraeger
@ 2008-10-13 8:36 ` Benjamin Herrenschmidt
2008-10-13 8:47 ` Christian Borntraeger
2008-10-14 0:38 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 24+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-13 8:36 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
> if (--hp->count == 0) {
> - if (hp->ops->notifier_del)
> - hp->ops->notifier_del(hp, hp->data);
> -
> /* We are done with the tty pointer now. */
> hp->tty = NULL;
> spin_unlock_irqrestore(&hp->lock, flags);
>
> + if (hp->ops->notifier_del)
> + hp->ops->notifier_del(hp, hp->data);
> +
I will try. Of course the risk here is that the interrupt happens
after we set hp->tty to NULL, so we probably need to check within the
interrupt handler for a NULL tty. I haven't checked if that's the case
(I'm not in front of the code right now).
Ben.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-10-13 8:36 ` Benjamin Herrenschmidt
@ 2008-10-13 8:47 ` Christian Borntraeger
2008-10-13 9:52 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 24+ messages in thread
From: Christian Borntraeger @ 2008-10-13 8:47 UTC (permalink / raw)
To: benh
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
Am Montag, 13. Oktober 2008 schrieb Benjamin Herrenschmidt:
>
> > if (--hp->count == 0) {
> > - if (hp->ops->notifier_del)
> > - hp->ops->notifier_del(hp, hp->data);
> > -
> > /* We are done with the tty pointer now. */
> > hp->tty = NULL;
> > spin_unlock_irqrestore(&hp->lock, flags);
> >
> > + if (hp->ops->notifier_del)
> > + hp->ops->notifier_del(hp, hp->data);
> > +
>
> I will try. Of course the risk here is that the interrupt happens
> after we set hp->tty to NULL, so we probably need to check within the
> interrupt handler for a NULL tty. I haven't checked if that's the case
> (I'm not in front of the code right now).
Even the old code (without my patch) was setting hp->tty to NULL before doing
the irq_free, so that should be ok.
Christian
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-10-13 8:47 ` Christian Borntraeger
@ 2008-10-13 9:52 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 24+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-13 9:52 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
On Mon, 2008-10-13 at 10:47 +0200, Christian Borntraeger wrote:
> > I will try. Of course the risk here is that the interrupt happens
> > after we set hp->tty to NULL, so we probably need to check within the
> > interrupt handler for a NULL tty. I haven't checked if that's the case
> > (I'm not in front of the code right now).
>
> Even the old code (without my patch) was setting hp->tty to NULL before doing
> the irq_free, so that should be ok.
Yup, just checked, it should be allright as long as it's cleared with
the spinlock held, which seems to be the case with your patch. I'll test
your fixup patch tomorrow to see if it clears the lockdep error.
Thanks !
Ben.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-10-13 7:51 ` Christian Borntraeger
2008-10-13 8:36 ` Benjamin Herrenschmidt
@ 2008-10-14 0:38 ` Benjamin Herrenschmidt
2008-10-14 6:42 ` Christian Borntraeger
1 sibling, 1 reply; 24+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-14 0:38 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
> Hmmm.
> Can you try if this patch fixes the lockdep trace?
Yup, the patch fixes it, I'll commit it via the powerpc.git tree if you
don't have any objection.
Cheers,
Ben.
> This would be analog to
> commit b1b135c8d619cb2c7045d6ee4e48375882518bb5
> Author: Christian Borntraeger <borntraeger@de.ibm.com>
> Date: Thu Aug 7 09:18:34 2008 +0200
>
> fix spinlock recursion in hvc_console
>
> commit 611e097d7707741a336a0677d9d69bec40f29f3d
> Author: Christian Borntraeger <borntraeger@de.ibm.com>
> hvc_console: rework setup to replace irq functions with callbacks
> introduced a spinlock recursion problem.
>
>
> Signed-off-by: Christian Borntraeger<borntraeger@de.ibm.com>
> ---
> drivers/char/hvc_console.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> Index: linux-2.6/drivers/char/hvc_console.c
> ===================================================================
> --- linux-2.6.orig/drivers/char/hvc_console.c
> +++ linux-2.6/drivers/char/hvc_console.c
> @@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct
> spin_lock_irqsave(&hp->lock, flags);
>
> if (--hp->count == 0) {
> - if (hp->ops->notifier_del)
> - hp->ops->notifier_del(hp, hp->data);
> -
> /* We are done with the tty pointer now. */
> hp->tty = NULL;
> spin_unlock_irqrestore(&hp->lock, flags);
>
> + if (hp->ops->notifier_del)
> + hp->ops->notifier_del(hp, hp->data);
> +
> /*
> * Chain calls chars_in_buffer() and returns immediately if
> * there is no buffered data otherwise sleeps on a wait queue
> @@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct
> hp->n_outbuf = 0;
> hp->tty = NULL;
>
> + spin_unlock_irqrestore(&hp->lock, flags);
> +
> if (hp->ops->notifier_del)
> hp->ops->notifier_del(hp, hp->data);
>
> - spin_unlock_irqrestore(&hp->lock, flags);
> -
> while(temp_open_count) {
> --temp_open_count;
> kref_put(&hp->kref, destroy_hvc_struct);
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-10-14 0:38 ` Benjamin Herrenschmidt
@ 2008-10-14 6:42 ` Christian Borntraeger
2008-10-14 8:18 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 24+ messages in thread
From: Christian Borntraeger @ 2008-10-14 6:42 UTC (permalink / raw)
To: benh
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
Am Dienstag, 14. Oktober 2008 schrieb Benjamin Herrenschmidt:
>
> > Hmmm.
> > Can you try if this patch fixes the lockdep trace?
>
> Yup, the patch fixes it, I'll commit it via the powerpc.git tree if you
> don't have any objection.
Sure, go ahead.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks
2008-10-14 6:42 ` Christian Borntraeger
@ 2008-10-14 8:18 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 24+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-14 8:18 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Jeremy Fitzhardinge, Virtualization Mailing List, Rusty Russell,
LKML, Linux PPC devel, Ingo Molnar
On Tue, 2008-10-14 at 08:42 +0200, Christian Borntraeger wrote:
> Am Dienstag, 14. Oktober 2008 schrieb Benjamin Herrenschmidt:
> >
> > > Hmmm.
> > > Can you try if this patch fixes the lockdep trace?
> >
> > Yup, the patch fixes it, I'll commit it via the powerpc.git tree if you
> > don't have any objection.
>
> Sure, go ahead.
Allright, I have a batch about ready to go to Linus, so I'll add that
and ask him to pull tomorrow.
Thanks,
Ben.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [RFC 2/3] virtio_console: use virtqueue notification for hvc_console
2008-06-03 12:44 [RFC 0/3]: hvc_console rework for platform without hard irqs Christian Borntraeger
2008-06-03 12:45 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks Christian Borntraeger
@ 2008-06-03 12:46 ` Christian Borntraeger
2008-06-03 17:24 ` Arnd Bergmann
2008-06-03 12:46 ` [RFC 3/3] s390: use virtio_console for KVM on s390 Christian Borntraeger
` (4 subsequent siblings)
6 siblings, 1 reply; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-03 12:46 UTC (permalink / raw)
To: Linux PPC devel
Cc: Virtualization Mailing List, Jeremy Fitzhardinge, Rusty Russell,
LKML
This patch exploits the new notifier callbacks of the hvc_console. We can
use the virtio callbacks instead of the polling code.
I also added a small Kconfig change that allows the user to specify the
virtio console in menuconfig.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
drivers/char/Kconfig | 6 +++++-
drivers/char/virtio_console.c | 27 +++++++++++++++++++++++++--
2 files changed, 30 insertions(+), 3 deletions(-)
Index: kvm/drivers/char/Kconfig
===================================================================
--- kvm.orig/drivers/char/Kconfig
+++ kvm/drivers/char/Kconfig
@@ -637,8 +637,12 @@ config HVC_XEN
Xen virtual console device driver
config VIRTIO_CONSOLE
- bool
+ bool "Virtio console"
+ depends on VIRTIO
select HVC_DRIVER
+ help
+ Virtio console for use with lguest and other hypervisors.
+
config HVCS
tristate "IBM Hypervisor Virtual Console Server support"
Index: kvm/drivers/char/virtio_console.c
===================================================================
--- kvm.orig/drivers/char/virtio_console.c
+++ kvm/drivers/char/virtio_console.c
@@ -46,6 +46,9 @@ static char *in, *inbuf;
/* The operations for our console. */
static struct hv_ops virtio_cons;
+/* The hvc device */
+struct hvc_struct *hvc;
+
/*D:310 The put_chars() callback is pretty straightforward.
*
* We turn the characters into a scatter-gather list, add it to the output
@@ -134,6 +137,25 @@ int __init virtio_cons_early_init(int (*
return hvc_instantiate(0, 0, &virtio_cons);
}
+/*
+ * we support only one console, the hvc struct is a global var
+ * There is no need to do anything
+ */
+static int notifier_add_vio(struct hvc_struct *hp, int data)
+{
+ return 0;
+}
+
+static void notifier_del_vio(struct hvc_struct *hp, int data)
+{
+}
+
+static void hvc_handle_input(struct virtqueue *vq)
+{
+ if (hvc_poll(hvc))
+ hvc_kick();
+}
+
/*D:370 Once we're further in boot, we get probed like any other virtio
device.
* At this stage we set up the output virtqueue.
*
@@ -144,7 +166,6 @@ int __init virtio_cons_early_init(int (*
static int __devinit virtcons_probe(struct virtio_device *dev)
{
int err;
- struct hvc_struct *hvc;
vdev = dev;
@@ -158,7 +179,7 @@ static int __devinit virtcons_probe(stru
/* Find the input queue. */
/* FIXME: This is why we want to wean off hvc: we do nothing
* when input comes in. */
- in_vq = vdev->config->find_vq(vdev, 0, NULL);
+ in_vq = vdev->config->find_vq(vdev, 0, hvc_handle_input);
if (IS_ERR(in_vq)) {
err = PTR_ERR(in_vq);
goto free;
@@ -173,6 +194,8 @@ static int __devinit virtcons_probe(stru
/* Start using the new console output. */
virtio_cons.get_chars = get_chars;
virtio_cons.put_chars = put_chars;
+ virtio_cons.notifier_add = notifier_add_vio;
+ virtio_cons.notifier_del = notifier_del_vio;
/* The first argument of hvc_alloc() is the virtual console number, so
* we use zero. The second argument is the interrupt number; we
^ permalink raw reply [flat|nested] 24+ messages in thread
* [RFC 3/3] s390: use virtio_console for KVM on s390
2008-06-03 12:44 [RFC 0/3]: hvc_console rework for platform without hard irqs Christian Borntraeger
2008-06-03 12:45 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks Christian Borntraeger
2008-06-03 12:46 ` [RFC 2/3] virtio_console: use virtqueue notification for hvc_console Christian Borntraeger
@ 2008-06-03 12:46 ` Christian Borntraeger
2008-06-03 12:49 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped) Christian Borntraeger
` (3 subsequent siblings)
6 siblings, 0 replies; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-03 12:46 UTC (permalink / raw)
To: Linux PPC devel
Cc: Virtualization Mailing List, Jeremy Fitzhardinge, Rusty Russell,
LKML
This patch enables virtio_console as the default console on kvm for
s390. We currently use the same notify hack as lguest for early
console output. I will try to address this for lguest and s390 later.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
arch/s390/Kconfig | 1 +
arch/s390/kernel/setup.c | 4 +++-
drivers/s390/kvm/kvm_virtio.c | 20 ++++++++++++++++++++
include/asm-s390/kvm_virtio.h | 10 ++++++++++
4 files changed, 34 insertions(+), 1 deletion(-)
Index: kvm/arch/s390/Kconfig
===================================================================
--- kvm.orig/arch/s390/Kconfig
+++ kvm/arch/s390/Kconfig
@@ -540,6 +540,7 @@ bool "s390 guest support (EXPERIMENTAL)"
depends on 64BIT && EXPERIMENTAL
select VIRTIO
select VIRTIO_RING
+ select VIRTIO_CONSOLE
help
Select this option if you want to run the kernel under s390 linux
endmenu
Index: kvm/arch/s390/kernel/setup.c
===================================================================
--- kvm.orig/arch/s390/kernel/setup.c
+++ kvm/arch/s390/kernel/setup.c
@@ -54,6 +54,7 @@
#include <asm/sections.h>
#include <asm/ebcdic.h>
#include <asm/compat.h>
+#include <asm/kvm_virtio.h>
long psw_kernel_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
@@ -799,7 +800,8 @@ setup_arch(char **cmdline_p)
printk("We are running under VM (64 bit mode)\n");
else if (MACHINE_IS_KVM) {
printk("We are running under KVM (64 bit mode)\n");
- add_preferred_console("ttyS", 1, NULL);
+ add_preferred_console("hvc", 0, NULL);
+ s390_virtio_console_init();
} else
printk("We are running native (64 bit mode)\n");
#endif /* CONFIG_64BIT */
Index: kvm/drivers/s390/kvm/kvm_virtio.c
===================================================================
--- kvm.orig/drivers/s390/kvm/kvm_virtio.c
+++ kvm/drivers/s390/kvm/kvm_virtio.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
+#include <linux/virtio_console.h>
#include <linux/interrupt.h>
#include <linux/virtio_ring.h>
#include <linux/pfn.h>
@@ -338,6 +339,25 @@ static int __init kvm_devices_init(void)
return 0;
}
+/* code for early console output with virtio_console */
+static __init int early_put_chars(u32 vtermno, const char *buf, int count)
+{
+ char scratch[17];
+ unsigned int len = count;
+
+ if (len > sizeof(scratch) - 1)
+ len = sizeof(scratch) - 1;
+ scratch[len] = '\0';
+ memcpy(scratch, buf, len);
+ kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, __pa(scratch));
+ return len;
+}
+
+void s390_virtio_console_init(void)
+{
+ virtio_cons_early_init(early_put_chars);
+}
+
/*
* We do this after core stuff, but before the drivers.
*/
Index: kvm/include/asm-s390/kvm_virtio.h
===================================================================
--- kvm.orig/include/asm-s390/kvm_virtio.h
+++ kvm/include/asm-s390/kvm_virtio.h
@@ -50,4 +50,14 @@ struct kvm_vqconfig {
#define KVM_S390_VIRTIO_RESET 1
#define KVM_S390_VIRTIO_SET_STATUS 2
+#ifdef __KERNEL__
+/* early virtio console setup */
+#ifdef CONFIG_VIRTIO_CONSOLE
+extern void s390_virtio_console_init(void);
+#else
+static inline void s390_virtio_console_init(void)
+{
+}
+#endif /* CONFIG_VIRTIO_CONSOLE */
+#endif /* __KERNEL__ */
#endif
^ permalink raw reply [flat|nested] 24+ messages in thread
* [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped)
2008-06-03 12:44 [RFC 0/3]: hvc_console rework for platform without hard irqs Christian Borntraeger
` (2 preceding siblings ...)
2008-06-03 12:46 ` [RFC 3/3] s390: use virtio_console for KVM on s390 Christian Borntraeger
@ 2008-06-03 12:49 ` Christian Borntraeger
2008-06-03 17:30 ` Arnd Bergmann
2008-06-04 9:06 ` Benjamin Herrenschmidt
2008-06-20 13:24 ` [RFC 1/3 v2] hvc_console: rework setup to replace irq functions with callbacks Christian Borntraeger
` (2 subsequent siblings)
6 siblings, 2 replies; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-03 12:49 UTC (permalink / raw)
To: Linux PPC devel
Cc: Virtualization Mailing List, Jeremy Fitzhardinge, Rusty Russell,
LKML
This patch tries to change hvc_console to not use request_irq/free_irq if
the backend does not use irqs. This allows virtio_console to use hvc_console
without having a linker reference to request_irq/free_irq.
The irq specific code is moved to hvc_irq.c and selected by the drivers that
use irqs (System p, System i, XEN).
I replaced "irq" with the opaque name "data". The request_irq and free_irq
calls are replaced with notifier_add and notifier_del. I have also changed
the code a bit to call the notifier_add and notifier_del inside the spinlock
area as the callbacks are found via hp->ops.
Feedback is appreciated.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: Rusty Russell <rusty@rustcorp.com.au>
CC: Jeremy Fitzhardinge <jeremy@goop.org>
CC: LKML <linux-kernel@vger.kernel.org>
CC: Virtualization Mailing List <virtualization@lists.osdl.org>
CC: Linux PPC devel <linuxppc-dev@ozlabs.org>
---
drivers/char/Kconfig | 8 ++++
drivers/char/Makefile | 1
drivers/char/hvc_console.c | 80 ++++++++++-----------------------------------
drivers/char/hvc_console.h | 34 ++++++++++++++++---
drivers/char/hvc_irq.c | 37 ++++++++++++++++++++
drivers/char/hvc_iseries.c | 2 +
drivers/char/hvc_vio.c | 2 +
drivers/char/hvc_xen.c | 2 +
8 files changed, 100 insertions(+), 66 deletions(-)
Index: kvm/drivers/char/Kconfig
===================================================================
--- kvm.orig/drivers/char/Kconfig
+++ kvm/drivers/char/Kconfig
@@ -588,11 +588,17 @@ config HVC_DRIVER
It will automatically be selected if one of the back-end console drivers
is selected.
+config HVC_IRQ
+ bool
+ help
+ Infrastructure for using the IRQ code for HVC console.
+ It will automatically be selected by the drivers that need it.
config HVC_CONSOLE
bool "pSeries Hypervisor Virtual Console support"
depends on PPC_PSERIES
select HVC_DRIVER
+ select HVC_IRQ
help
pSeries machines when partitioned support a hypervisor virtual
console. This driver allows each pSeries partition to have a console
@@ -603,6 +609,7 @@ config HVC_ISERIES
depends on PPC_ISERIES
default y
select HVC_DRIVER
+ select HVC_IRQ
help
iSeries machines support a hypervisor virtual console.
@@ -624,6 +631,7 @@ config HVC_XEN
bool "Xen Hypervisor Console support"
depends on XEN
select HVC_DRIVER
+ select HVC_IRQ
default y
help
Xen virtual console device driver
Index: kvm/drivers/char/Makefile
===================================================================
--- kvm.orig/drivers/char/Makefile
+++ kvm/drivers/char/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_HVC_ISERIES) += hvc_iseries
obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
+obj-$(CONFIG_HVC_IRQ) += hvc_irq.o
obj-$(CONFIG_HVC_XEN) += hvc_xen.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
Index: kvm/drivers/char/hvc_console.c
===================================================================
--- kvm.orig/drivers/char/hvc_console.c
+++ kvm/drivers/char/hvc_console.c
@@ -75,23 +75,6 @@ static int hvc_init(void);
static int sysrq_pressed;
#endif
-struct hvc_struct {
- spinlock_t lock;
- int index;
- struct tty_struct *tty;
- unsigned int count;
- int do_wakeup;
- char *outbuf;
- int outbuf_size;
- int n_outbuf;
- uint32_t vtermno;
- struct hv_ops *ops;
- int irq_requested;
- int irq;
- struct list_head next;
- struct kref kref; /* ref count & hvc_struct lifetime */
-};
-
/* dynamic list of hvc_struct instances */
static LIST_HEAD(hvc_structs);
@@ -300,26 +283,12 @@ int hvc_instantiate(uint32_t vtermno, in
}
/* Wake the sleeping khvcd */
-static void hvc_kick(void)
+void hvc_kick(void)
{
hvc_kicked = 1;
wake_up_process(hvc_task);
}
-static int hvc_poll(struct hvc_struct *hp);
-
-/*
- * NOTE: This API isn't used if the console adapter doesn't support interrupts.
- * In this case the console is poll driven.
- */
-static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
-{
- /* if hvc_poll request a repoll, then kick the hvcd thread */
- if (hvc_poll(dev_instance))
- hvc_kick();
- return IRQ_HANDLED;
-}
-
static void hvc_unthrottle(struct tty_struct *tty)
{
hvc_kick();
@@ -333,7 +302,6 @@ static int hvc_open(struct tty_struct *t
{
struct hvc_struct *hp;
unsigned long flags;
- int irq = 0;
int rc = 0;
/* Auto increments kref reference if found. */
@@ -352,18 +320,15 @@ static int hvc_open(struct tty_struct *t
tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */
hp->tty = tty;
- /* Save for request_irq outside of spin_lock. */
- irq = hp->irq;
- if (irq)
- hp->irq_requested = 1;
+
+ if (hp->ops->notifier_add)
+ rc = hp->ops->notifier_add(hp, hp->data);
spin_unlock_irqrestore(&hp->lock, flags);
- /* check error, fallback to non-irq */
- if (irq)
- rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, "hvc_console", hp);
+
/*
- * If the request_irq() fails and we return an error. The tty layer
+ * If the notifier fails we return an error. The tty layer
* will call hvc_close() after a failed open but we don't want to clean
* up there so we'll clean up here and clear out the previously set
* tty fields and return the kref reference.
@@ -371,7 +336,6 @@ static int hvc_open(struct tty_struct *t
if (rc) {
spin_lock_irqsave(&hp->lock, flags);
hp->tty = NULL;
- hp->irq_requested = 0;
spin_unlock_irqrestore(&hp->lock, flags);
tty->driver_data = NULL;
kref_put(&hp->kref, destroy_hvc_struct);
@@ -386,7 +350,6 @@ static int hvc_open(struct tty_struct *t
static void hvc_close(struct tty_struct *tty, struct file * filp)
{
struct hvc_struct *hp;
- int irq = 0;
unsigned long flags;
if (tty_hung_up_p(filp))
@@ -404,9 +367,8 @@ static void hvc_close(struct tty_struct
spin_lock_irqsave(&hp->lock, flags);
if (--hp->count == 0) {
- if (hp->irq_requested)
- irq = hp->irq;
- hp->irq_requested = 0;
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
/* We are done with the tty pointer now. */
hp->tty = NULL;
@@ -418,10 +380,6 @@ static void hvc_close(struct tty_struct
* waking periodically to check chars_in_buffer().
*/
tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
-
- if (irq)
- free_irq(irq, hp);
-
} else {
if (hp->count < 0)
printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
@@ -436,7 +394,6 @@ static void hvc_hangup(struct tty_struct
{
struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
- int irq = 0;
int temp_open_count;
if (!hp)
@@ -458,13 +415,12 @@ static void hvc_hangup(struct tty_struct
hp->count = 0;
hp->n_outbuf = 0;
hp->tty = NULL;
- if (hp->irq_requested)
- /* Saved for use outside of spin_lock. */
- irq = hp->irq;
- hp->irq_requested = 0;
+
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
+
spin_unlock_irqrestore(&hp->lock, flags);
- if (irq)
- free_irq(irq, hp);
+
while(temp_open_count) {
--temp_open_count;
kref_put(&hp->kref, destroy_hvc_struct);
@@ -575,7 +531,7 @@ static u32 timeout = MIN_TIMEOUT;
#define HVC_POLL_READ 0x00000001
#define HVC_POLL_WRITE 0x00000002
-static int hvc_poll(struct hvc_struct *hp)
+int hvc_poll(struct hvc_struct *hp)
{
struct tty_struct *tty;
int i, n, poll_mask = 0;
@@ -602,10 +558,10 @@ static int hvc_poll(struct hvc_struct *h
if (test_bit(TTY_THROTTLED, &tty->flags))
goto throttled;
- /* If we aren't interrupt driven and aren't throttled, we always
+ /* If we aren't notifier driven and aren't throttled, we always
* request a reschedule
*/
- if (hp->irq == 0)
+ if (!hp->ops->notifier_add)
poll_mask |= HVC_POLL_READ;
/* Read data if any */
@@ -739,7 +695,7 @@ static const struct tty_operations hvc_o
.chars_in_buffer = hvc_chars_in_buffer,
};
-struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
+struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size)
{
struct hvc_struct *hp;
@@ -760,7 +716,7 @@ struct hvc_struct __devinit *hvc_alloc(u
memset(hp, 0x00, sizeof(*hp));
hp->vtermno = vtermno;
- hp->irq = irq;
+ hp->data = data;
hp->ops = ops;
hp->outbuf_size = outbuf_size;
hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
Index: kvm/drivers/char/hvc_console.h
===================================================================
--- kvm.orig/drivers/char/hvc_console.h
+++ kvm/drivers/char/hvc_console.h
@@ -42,22 +42,48 @@
*/
#define HVC_ALLOC_TTY_ADAPTERS 8
+struct hvc_struct {
+ spinlock_t lock;
+ int index;
+ struct tty_struct *tty;
+ unsigned int count;
+ int do_wakeup;
+ char *outbuf;
+ int outbuf_size;
+ int n_outbuf;
+ uint32_t vtermno;
+ struct hv_ops *ops;
+ int data;
+ struct list_head next;
+ struct kref kref; /* ref count & hvc_struct lifetime */
+};
/* implemented by a low level driver */
struct hv_ops {
int (*get_chars)(uint32_t vtermno, char *buf, int count);
int (*put_chars)(uint32_t vtermno, const char *buf, int count);
-};
-struct hvc_struct;
+ /* Callbacks for notification. Called in open and close */
+ int (*notifier_add)(struct hvc_struct *hp, int data);
+ void (*notifier_del)(struct hvc_struct *hp, int data);
+};
/* Register a vterm and a slot index for use as a console (console_init) */
extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
/* register a vterm for hvc tty operation (module_init or hotplug add) */
-extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
+extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size);
-/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
+/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
extern int __devexit hvc_remove(struct hvc_struct *hp);
+/* data available */
+int hvc_poll(struct hvc_struct *hp);
+void hvc_kick(void);
+
+#ifdef CONFIG_HVC_IRQ
+/* default notifier for irq based notification */
+extern int notifier_add_irq(struct hvc_struct *hp, int irq);
+extern void notifier_del_irq(struct hvc_struct *hp, int irq);
+#endif
#endif // HVC_CONSOLE_H
Index: kvm/drivers/char/hvc_irq.c
===================================================================
--- /dev/null
+++ kvm/drivers/char/hvc_irq.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright IBM Corp. 2001,2008
+ *
+ * This file contains the IRQ specific code for hvc_console
+ *
+ */
+
+#include <linux/interrupt.h>
+
+#include "hvc_console.h"
+
+static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
+{
+ /* if hvc_poll request a repoll, then kick the hvcd thread */
+ if (hvc_poll(dev_instance))
+ hvc_kick();
+ return IRQ_HANDLED;
+}
+
+/*
+ * For IRQ based systems these callbacks can be used
+ */
+int notifier_add_irq(struct hvc_struct *hp, int irq)
+{
+ if (!irq)
+ return 0;
+ return request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED,
+ "hvc_console", hp);
+}
+
+void notifier_del_irq(struct hvc_struct *hp, int irq)
+{
+ if (!irq)
+ return;
+ free_irq(irq, hp);
+}
+
Index: kvm/drivers/char/hvc_iseries.c
===================================================================
--- kvm.orig/drivers/char/hvc_iseries.c
+++ kvm/drivers/char/hvc_iseries.c
@@ -200,6 +200,8 @@ done:
static struct hv_ops hvc_get_put_ops = {
.get_chars = get_chars,
.put_chars = put_chars,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
Index: kvm/drivers/char/hvc_vio.c
===================================================================
--- kvm.orig/drivers/char/hvc_vio.c
+++ kvm/drivers/char/hvc_vio.c
@@ -80,6 +80,8 @@ static int filtered_get_chars(uint32_t v
static struct hv_ops hvc_get_put_ops = {
.get_chars = filtered_get_chars,
.put_chars = hvc_put_chars,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
Index: kvm/drivers/char/hvc_xen.c
===================================================================
--- kvm.orig/drivers/char/hvc_xen.c
+++ kvm/drivers/char/hvc_xen.c
@@ -95,6 +95,8 @@ static int read_console(uint32_t vtermno
static struct hv_ops hvc_ops = {
.get_chars = read_console,
.put_chars = write_console,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __init xen_init(void)
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped)
2008-06-03 12:49 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped) Christian Borntraeger
@ 2008-06-03 17:30 ` Arnd Bergmann
2008-06-04 8:00 ` Christian Borntraeger
2008-06-04 9:06 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 24+ messages in thread
From: Arnd Bergmann @ 2008-06-03 17:30 UTC (permalink / raw)
To: linuxppc-dev
Cc: Christian Borntraeger, Jeremy Fitzhardinge, Rusty Russell, LKML,
Virtualization Mailing List
On Tuesday 03 June 2008, Christian Borntraeger wrote:
> @@ -42,22 +42,48 @@
> */
> #define HVC_ALLOC_TTY_ADAPTERS 8
>
> +struct hvc_struct {
> + spinlock_t lock;
> + int index;
> + struct tty_struct *tty;
> + unsigned int count;
> + int do_wakeup;
> + char *outbuf;
> + int outbuf_size;
> + int n_outbuf;
> + uint32_t vtermno;
> + struct hv_ops *ops;
> + int data;
> + struct list_head next;
> + struct kref kref; /* ref count & hvc_struct lifetime */
> +};
>
I don't see a reason to make this data structure known to other files,
so why not leave it in hvc_console.c?
> +
> +#ifdef CONFIG_HVC_IRQ
> +/* default notifier for irq based notification */
> +extern int notifier_add_irq(struct hvc_struct *hp, int irq);
> +extern void notifier_del_irq(struct hvc_struct *hp, int irq);
> +#endif
> #endif // HVC_CONSOLE_H
Please remove the #ifdef around the declarations.
h Arnd <><
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped)
2008-06-03 17:30 ` Arnd Bergmann
@ 2008-06-04 8:00 ` Christian Borntraeger
0 siblings, 0 replies; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-04 8:00 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linuxppc-dev, Jeremy Fitzhardinge, Rusty Russell, LKML,
Virtualization Mailing List
Am Dienstag, 3. Juni 2008 schrieb Arnd Bergmann:
> I don't see a reason to make this data structure known to other files,
> so why not leave it in hvc_console.c?
Yes, Fixed. I moved it for a ealier version of this patch. Currently its not
necessary. Dont know if I need to move it again if I work on Rusty's ideas.
Christian
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped)
2008-06-03 12:49 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped) Christian Borntraeger
2008-06-03 17:30 ` Arnd Bergmann
@ 2008-06-04 9:06 ` Benjamin Herrenschmidt
1 sibling, 0 replies; 24+ messages in thread
From: Benjamin Herrenschmidt @ 2008-06-04 9:06 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Linux PPC devel, Jeremy Fitzhardinge, Rusty Russell, LKML,
Virtualization Mailing List
On Tue, 2008-06-03 at 14:49 +0200, Christian Borntraeger wrote:
> This patch tries to change hvc_console to not use request_irq/free_irq if
> the backend does not use irqs. This allows virtio_console to use hvc_console
> without having a linker reference to request_irq/free_irq.
>
> The irq specific code is moved to hvc_irq.c and selected by the drivers that
> use irqs (System p, System i, XEN).
>
> I replaced "irq" with the opaque name "data". The request_irq and free_irq
> calls are replaced with notifier_add and notifier_del. I have also changed
> the code a bit to call the notifier_add and notifier_del inside the spinlock
> area as the callbacks are found via hp->ops.
>
> Feedback is appreciated.
I haven't looked at the patch proper but I agree with the basic
premises. We routinely use hvc_console for things that don't have an
irq. In fact, David even did a backend hooking up to udbg which is
useful when bringing up weird stuffs :-)
Cheers,
Ben.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [RFC 1/3 v2] hvc_console: rework setup to replace irq functions with callbacks
2008-06-03 12:44 [RFC 0/3]: hvc_console rework for platform without hard irqs Christian Borntraeger
` (3 preceding siblings ...)
2008-06-03 12:49 ` [RFC 1/3] hvc_console: rework setup to replace irq functions with callbacks (not word wrapped) Christian Borntraeger
@ 2008-06-20 13:24 ` Christian Borntraeger
2008-06-27 5:27 ` Rusty Russell
2008-06-20 13:24 ` [RFC 2/3 v2] virtio_console: use virtqueue notification for hvc_console Christian Borntraeger
2008-06-20 13:24 ` [RFC 3/3 v2] s390: use virtio_console for KVM on s390 Christian Borntraeger
6 siblings, 1 reply; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-20 13:24 UTC (permalink / raw)
To: Linux PPC devel
Cc: Yajin, Virtualization Mailing List, Jeremy Fitzhardinge,
Rusty Russell, LKML
This patch tries to change hvc_console to not use request_irq/free_irq if
the backend does not use irqs. This allows virtio_console to use hvc_console
without having a linker reference to request_irq/free_irq.
In addition, together with patch 2/3 it improves the performance for virtio
console input. (an earlier version of this patch was tested by Yajin on lguest)
The irq specific code is moved to hvc_irq.c and selected by the drivers that
use irqs (System p, System i, XEN).
I replaced "int irq" with the opaque "int data". The request_irq and
free_irq calls are replaced with notifier_add and notifier_del. I have also
changed the code a bit to call the notifier_add and notifier_del inside the
spinlock area as the callbacks are found via hp->ops.
Changes since last version:
o remove ifdef
o reintroduce "irq_requested" as "notified"
o cleanups, sparse..
I did not move the timer based polling into a separate polling scheme. I
played with several variants, but it seems we need to sleep/schedule in
a thread even for irq based consoles, as there are throttleing and buffer
size constraints.
I also kept hvc_struct defined in hvc_console.h so that hvc_irq.c can access
the irq_requested element.
Feedback is appreciated. virtio_console is currently the only available console
for kvm on s390. I plan to push this change as soon as all affected parties
agree on it. I would love to get test results from System p, Xen etc.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
drivers/char/Kconfig | 5 ++
drivers/char/Makefile | 1
drivers/char/hvc_console.c | 80 ++++++++++-----------------------------------
drivers/char/hvc_console.h | 34 ++++++++++++++++---
drivers/char/hvc_irq.c | 45 +++++++++++++++++++++++++
drivers/char/hvc_iseries.c | 2 +
drivers/char/hvc_vio.c | 2 +
drivers/char/hvc_xen.c | 2 +
8 files changed, 105 insertions(+), 66 deletions(-)
Index: kvm/drivers/char/Kconfig
===================================================================
--- kvm.orig/drivers/char/Kconfig
+++ kvm/drivers/char/Kconfig
@@ -588,11 +588,14 @@ config HVC_DRIVER
It will automatically be selected if one of the back-end console drivers
is selected.
+config HVC_IRQ
+ bool
config HVC_CONSOLE
bool "pSeries Hypervisor Virtual Console support"
depends on PPC_PSERIES
select HVC_DRIVER
+ select HVC_IRQ
help
pSeries machines when partitioned support a hypervisor virtual
console. This driver allows each pSeries partition to have a console
@@ -603,6 +606,7 @@ config HVC_ISERIES
depends on PPC_ISERIES
default y
select HVC_DRIVER
+ select HVC_IRQ
help
iSeries machines support a hypervisor virtual console.
@@ -624,6 +628,7 @@ config HVC_XEN
bool "Xen Hypervisor Console support"
depends on XEN
select HVC_DRIVER
+ select HVC_IRQ
default y
help
Xen virtual console device driver
Index: kvm/drivers/char/Makefile
===================================================================
--- kvm.orig/drivers/char/Makefile
+++ kvm/drivers/char/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_HVC_ISERIES) += hvc_iseries
obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
+obj-$(CONFIG_HVC_IRQ) += hvc_irq.o
obj-$(CONFIG_HVC_XEN) += hvc_xen.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
Index: kvm/drivers/char/hvc_console.c
===================================================================
--- kvm.orig/drivers/char/hvc_console.c
+++ kvm/drivers/char/hvc_console.c
@@ -75,23 +75,6 @@ static int hvc_init(void);
static int sysrq_pressed;
#endif
-struct hvc_struct {
- spinlock_t lock;
- int index;
- struct tty_struct *tty;
- unsigned int count;
- int do_wakeup;
- char *outbuf;
- int outbuf_size;
- int n_outbuf;
- uint32_t vtermno;
- struct hv_ops *ops;
- int irq_requested;
- int irq;
- struct list_head next;
- struct kref kref; /* ref count & hvc_struct lifetime */
-};
-
/* dynamic list of hvc_struct instances */
static LIST_HEAD(hvc_structs);
@@ -300,26 +283,12 @@ int hvc_instantiate(uint32_t vtermno, in
}
/* Wake the sleeping khvcd */
-static void hvc_kick(void)
+void hvc_kick(void)
{
hvc_kicked = 1;
wake_up_process(hvc_task);
}
-static int hvc_poll(struct hvc_struct *hp);
-
-/*
- * NOTE: This API isn't used if the console adapter doesn't support interrupts.
- * In this case the console is poll driven.
- */
-static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
-{
- /* if hvc_poll request a repoll, then kick the hvcd thread */
- if (hvc_poll(dev_instance))
- hvc_kick();
- return IRQ_HANDLED;
-}
-
static void hvc_unthrottle(struct tty_struct *tty)
{
hvc_kick();
@@ -333,7 +302,6 @@ static int hvc_open(struct tty_struct *t
{
struct hvc_struct *hp;
unsigned long flags;
- int irq = 0;
int rc = 0;
/* Auto increments kref reference if found. */
@@ -352,18 +320,15 @@ static int hvc_open(struct tty_struct *t
tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */
hp->tty = tty;
- /* Save for request_irq outside of spin_lock. */
- irq = hp->irq;
- if (irq)
- hp->irq_requested = 1;
+
+ if (hp->ops->notifier_add)
+ rc = hp->ops->notifier_add(hp, hp->data);
spin_unlock_irqrestore(&hp->lock, flags);
- /* check error, fallback to non-irq */
- if (irq)
- rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, "hvc_console", hp);
+
/*
- * If the request_irq() fails and we return an error. The tty layer
+ * If the notifier fails we return an error. The tty layer
* will call hvc_close() after a failed open but we don't want to clean
* up there so we'll clean up here and clear out the previously set
* tty fields and return the kref reference.
@@ -371,7 +336,6 @@ static int hvc_open(struct tty_struct *t
if (rc) {
spin_lock_irqsave(&hp->lock, flags);
hp->tty = NULL;
- hp->irq_requested = 0;
spin_unlock_irqrestore(&hp->lock, flags);
tty->driver_data = NULL;
kref_put(&hp->kref, destroy_hvc_struct);
@@ -386,7 +350,6 @@ static int hvc_open(struct tty_struct *t
static void hvc_close(struct tty_struct *tty, struct file * filp)
{
struct hvc_struct *hp;
- int irq = 0;
unsigned long flags;
if (tty_hung_up_p(filp))
@@ -404,9 +367,8 @@ static void hvc_close(struct tty_struct
spin_lock_irqsave(&hp->lock, flags);
if (--hp->count == 0) {
- if (hp->irq_requested)
- irq = hp->irq;
- hp->irq_requested = 0;
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
/* We are done with the tty pointer now. */
hp->tty = NULL;
@@ -418,10 +380,6 @@ static void hvc_close(struct tty_struct
* waking periodically to check chars_in_buffer().
*/
tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
-
- if (irq)
- free_irq(irq, hp);
-
} else {
if (hp->count < 0)
printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
@@ -436,7 +394,6 @@ static void hvc_hangup(struct tty_struct
{
struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
- int irq = 0;
int temp_open_count;
if (!hp)
@@ -458,13 +415,12 @@ static void hvc_hangup(struct tty_struct
hp->count = 0;
hp->n_outbuf = 0;
hp->tty = NULL;
- if (hp->irq_requested)
- /* Saved for use outside of spin_lock. */
- irq = hp->irq;
- hp->irq_requested = 0;
+
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
+
spin_unlock_irqrestore(&hp->lock, flags);
- if (irq)
- free_irq(irq, hp);
+
while(temp_open_count) {
--temp_open_count;
kref_put(&hp->kref, destroy_hvc_struct);
@@ -575,7 +531,7 @@ static u32 timeout = MIN_TIMEOUT;
#define HVC_POLL_READ 0x00000001
#define HVC_POLL_WRITE 0x00000002
-static int hvc_poll(struct hvc_struct *hp)
+int hvc_poll(struct hvc_struct *hp)
{
struct tty_struct *tty;
int i, n, poll_mask = 0;
@@ -602,10 +558,10 @@ static int hvc_poll(struct hvc_struct *h
if (test_bit(TTY_THROTTLED, &tty->flags))
goto throttled;
- /* If we aren't interrupt driven and aren't throttled, we always
+ /* If we aren't notifier driven and aren't throttled, we always
* request a reschedule
*/
- if (hp->irq == 0)
+ if (!hp->irq_requested)
poll_mask |= HVC_POLL_READ;
/* Read data if any */
@@ -739,7 +695,7 @@ static const struct tty_operations hvc_o
.chars_in_buffer = hvc_chars_in_buffer,
};
-struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
+struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size)
{
struct hvc_struct *hp;
@@ -760,7 +716,7 @@ struct hvc_struct __devinit *hvc_alloc(u
memset(hp, 0x00, sizeof(*hp));
hp->vtermno = vtermno;
- hp->irq = irq;
+ hp->data = data;
hp->ops = ops;
hp->outbuf_size = outbuf_size;
hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
Index: kvm/drivers/char/hvc_console.h
===================================================================
--- kvm.orig/drivers/char/hvc_console.h
+++ kvm/drivers/char/hvc_console.h
@@ -42,22 +42,48 @@
*/
#define HVC_ALLOC_TTY_ADAPTERS 8
+struct hvc_struct {
+ spinlock_t lock;
+ int index;
+ struct tty_struct *tty;
+ unsigned int count;
+ int do_wakeup;
+ char *outbuf;
+ int outbuf_size;
+ int n_outbuf;
+ uint32_t vtermno;
+ struct hv_ops *ops;
+ int irq_requested;
+ int data;
+ struct list_head next;
+ struct kref kref; /* ref count & hvc_struct lifetime */
+};
/* implemented by a low level driver */
struct hv_ops {
int (*get_chars)(uint32_t vtermno, char *buf, int count);
int (*put_chars)(uint32_t vtermno, const char *buf, int count);
-};
-struct hvc_struct;
+ /* Callbacks for notification. Called in open and close */
+ int (*notifier_add)(struct hvc_struct *hp, int irq);
+ void (*notifier_del)(struct hvc_struct *hp, int irq);
+};
/* Register a vterm and a slot index for use as a console (console_init) */
extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
/* register a vterm for hvc tty operation (module_init or hotplug add) */
-extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
+extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size);
-/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
+/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
extern int __devexit hvc_remove(struct hvc_struct *hp);
+/* data available */
+int hvc_poll(struct hvc_struct *hp);
+void hvc_kick(void);
+
+/* default notifier for irq based notification */
+extern int notifier_add_irq(struct hvc_struct *hp, int data);
+extern void notifier_del_irq(struct hvc_struct *hp, int data);
+
#endif // HVC_CONSOLE_H
Index: kvm/drivers/char/hvc_irq.c
===================================================================
--- /dev/null
+++ kvm/drivers/char/hvc_irq.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright IBM Corp. 2001,2008
+ *
+ * This file contains the IRQ specific code for hvc_console
+ *
+ */
+
+#include <linux/interrupt.h>
+
+#include "hvc_console.h"
+
+static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
+{
+ /* if hvc_poll request a repoll, then kick the hvcd thread */
+ if (hvc_poll(dev_instance))
+ hvc_kick();
+ return IRQ_HANDLED;
+}
+
+/*
+ * For IRQ based systems these callbacks can be used
+ */
+int notifier_add_irq(struct hvc_struct *hp, int irq)
+{
+ int rc;
+
+ if (!irq) {
+ hp->irq_requested = 0;
+ return 0;
+ }
+ rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED,
+ "hvc_console", hp);
+ if (!rc)
+ hp->irq_requested = 1;
+ return rc;
+}
+
+void notifier_del_irq(struct hvc_struct *hp, int irq)
+{
+ if (!irq)
+ return;
+ free_irq(irq, hp);
+ hp->irq_requested = 0;
+}
+
Index: kvm/drivers/char/hvc_iseries.c
===================================================================
--- kvm.orig/drivers/char/hvc_iseries.c
+++ kvm/drivers/char/hvc_iseries.c
@@ -200,6 +200,8 @@ done:
static struct hv_ops hvc_get_put_ops = {
.get_chars = get_chars,
.put_chars = put_chars,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
Index: kvm/drivers/char/hvc_vio.c
===================================================================
--- kvm.orig/drivers/char/hvc_vio.c
+++ kvm/drivers/char/hvc_vio.c
@@ -80,6 +80,8 @@ static int filtered_get_chars(uint32_t v
static struct hv_ops hvc_get_put_ops = {
.get_chars = filtered_get_chars,
.put_chars = hvc_put_chars,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
Index: kvm/drivers/char/hvc_xen.c
===================================================================
--- kvm.orig/drivers/char/hvc_xen.c
+++ kvm/drivers/char/hvc_xen.c
@@ -95,6 +95,8 @@ static int read_console(uint32_t vtermno
static struct hv_ops hvc_ops = {
.get_chars = read_console,
.put_chars = write_console,
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
};
static int __init xen_init(void)
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [RFC 1/3 v2] hvc_console: rework setup to replace irq functions with callbacks
2008-06-20 13:24 ` [RFC 1/3 v2] hvc_console: rework setup to replace irq functions with callbacks Christian Borntraeger
@ 2008-06-27 5:27 ` Rusty Russell
0 siblings, 0 replies; 24+ messages in thread
From: Rusty Russell @ 2008-06-27 5:27 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Linux PPC devel, Jeremy Fitzhardinge, Yajin, LKML,
Virtualization Mailing List
On Friday 20 June 2008 23:24:08 Christian Borntraeger wrote:
> I also kept hvc_struct defined in hvc_console.h so that hvc_irq.c can
> access the irq_requested element.
Added this fix:
=46ix compile of hvc_rtas.c
Moving the struct definition out to the header had bad effect under one
ppc64 config that I tried:
drivers/char/hvc_console.h:59: error: field =E2=80=98kref=E2=80=99 has inco=
mplete type
So move the include of kref.h too.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff -r f382d8f562a8 drivers/char/hvc_console.c
=2D-- a/drivers/char/hvc_console.c Fri Jun 27 15:17:49 2008 +1000
+++ b/drivers/char/hvc_console.c Fri Jun 27 15:24:15 2008 +1000
@@ -27,7 +27,6 @@
#include <linux/init.h>
#include <linux/kbd_kern.h>
#include <linux/kernel.h>
=2D#include <linux/kref.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/module.h>
diff -r f382d8f562a8 drivers/char/hvc_console.h
=2D-- a/drivers/char/hvc_console.h Fri Jun 27 15:17:49 2008 +1000
+++ b/drivers/char/hvc_console.h Fri Jun 27 15:24:15 2008 +1000
@@ -26,6 +26,7 @@
=20
#ifndef HVC_CONSOLE_H
#define HVC_CONSOLE_H
+#include <linux/kref.h>
=20
/*
* This is the max number of console adapters that can/will be found as
^ permalink raw reply [flat|nested] 24+ messages in thread
* [RFC 2/3 v2] virtio_console: use virtqueue notification for hvc_console
2008-06-03 12:44 [RFC 0/3]: hvc_console rework for platform without hard irqs Christian Borntraeger
` (4 preceding siblings ...)
2008-06-20 13:24 ` [RFC 1/3 v2] hvc_console: rework setup to replace irq functions with callbacks Christian Borntraeger
@ 2008-06-20 13:24 ` Christian Borntraeger
2008-06-20 13:24 ` [RFC 3/3 v2] s390: use virtio_console for KVM on s390 Christian Borntraeger
6 siblings, 0 replies; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-20 13:24 UTC (permalink / raw)
To: Linux PPC devel
Cc: Yajin, Virtualization Mailing List, Jeremy Fitzhardinge,
Rusty Russell, LKML
This patch exploits the new notifier callbacks of the hvc_console. We can
use the virtio callbacks instead of the polling code.
I also added a small Kconfig change that allows the user to specify the
virtio console in menuconfig.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
drivers/char/Kconfig | 6 +++++-
drivers/char/virtio_console.c | 40 +++++++++++++++++++++++++++++++++-------
2 files changed, 38 insertions(+), 8 deletions(-)
Index: kvm/drivers/char/Kconfig
===================================================================
--- kvm.orig/drivers/char/Kconfig
+++ kvm/drivers/char/Kconfig
@@ -634,8 +634,12 @@ config HVC_XEN
Xen virtual console device driver
config VIRTIO_CONSOLE
- bool
+ bool "Virtio console"
+ depends on VIRTIO
select HVC_DRIVER
+ help
+ Virtio console for use with lguest and other hypervisors.
+
config HVCS
tristate "IBM Hypervisor Virtual Console Server support"
Index: kvm/drivers/char/virtio_console.c
===================================================================
--- kvm.orig/drivers/char/virtio_console.c
+++ kvm/drivers/char/virtio_console.c
@@ -46,6 +46,9 @@ static char *in, *inbuf;
/* The operations for our console. */
static struct hv_ops virtio_cons;
+/* The hvc device */
+static struct hvc_struct *hvc;
+
/*D:310 The put_chars() callback is pretty straightforward.
*
* We turn the characters into a scatter-gather list, add it to the output
@@ -134,6 +137,27 @@ int __init virtio_cons_early_init(int (*
return hvc_instantiate(0, 0, &virtio_cons);
}
+/*
+ * we support only one console, the hvc struct is a global var
+ * There is no need to do anything
+ */
+static int notifier_add_vio(struct hvc_struct *hp, int data)
+{
+ hp->irq_requested = 1;
+ return 0;
+}
+
+static void notifier_del_vio(struct hvc_struct *hp, int data)
+{
+ hp->irq_requested = 0;
+}
+
+static void hvc_handle_input(struct virtqueue *vq)
+{
+ if (hvc_poll(hvc))
+ hvc_kick();
+}
+
/*D:370 Once we're further in boot, we get probed like any other virtio device.
* At this stage we set up the output virtqueue.
*
@@ -144,7 +168,6 @@ int __init virtio_cons_early_init(int (*
static int __devinit virtcons_probe(struct virtio_device *dev)
{
int err;
- struct hvc_struct *hvc;
vdev = dev;
@@ -158,7 +181,7 @@ static int __devinit virtcons_probe(stru
/* Find the input queue. */
/* FIXME: This is why we want to wean off hvc: we do nothing
* when input comes in. */
- in_vq = vdev->config->find_vq(vdev, 0, NULL);
+ in_vq = vdev->config->find_vq(vdev, 0, hvc_handle_input);
if (IS_ERR(in_vq)) {
err = PTR_ERR(in_vq);
goto free;
@@ -173,15 +196,18 @@ static int __devinit virtcons_probe(stru
/* Start using the new console output. */
virtio_cons.get_chars = get_chars;
virtio_cons.put_chars = put_chars;
+ virtio_cons.notifier_add = notifier_add_vio;
+ virtio_cons.notifier_del = notifier_del_vio;
/* The first argument of hvc_alloc() is the virtual console number, so
- * we use zero. The second argument is the interrupt number; we
- * currently leave this as zero: it would be better not to use the
- * hvc mechanism and fix this (FIXME!).
+ * we use zero. The second argument is the parameter for the
+ * notification mechanism (like irq number). We currently leave this
+ * as zero, virtqueues have implicit notifications.
*
* The third argument is a "struct hv_ops" containing the put_chars()
- * and get_chars() pointers. The final argument is the output buffer
- * size: we can do any size, so we put PAGE_SIZE here. */
+ * get_chars(), notifier_add() and notifier_del() pointers.
+ * The final argument is the output buffer size: we can do any size,
+ * so we put PAGE_SIZE here. */
hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE);
if (IS_ERR(hvc)) {
err = PTR_ERR(hvc);
^ permalink raw reply [flat|nested] 24+ messages in thread
* [RFC 3/3 v2] s390: use virtio_console for KVM on s390
2008-06-03 12:44 [RFC 0/3]: hvc_console rework for platform without hard irqs Christian Borntraeger
` (5 preceding siblings ...)
2008-06-20 13:24 ` [RFC 2/3 v2] virtio_console: use virtqueue notification for hvc_console Christian Borntraeger
@ 2008-06-20 13:24 ` Christian Borntraeger
2008-06-23 3:04 ` Rusty Russell
6 siblings, 1 reply; 24+ messages in thread
From: Christian Borntraeger @ 2008-06-20 13:24 UTC (permalink / raw)
To: Linux PPC devel
Cc: Virtualization Mailing List, Jeremy Fitzhardinge, Rusty Russell,
LKML
This patch enables virtio_console as the default console on kvm for
s390. We currently use the same notify hack as lguest for early
console output. I will try to address this for lguest and s390 later.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
arch/s390/Kconfig | 1 +
arch/s390/kernel/setup.c | 4 +++-
drivers/s390/kvm/kvm_virtio.c | 20 ++++++++++++++++++++
include/asm-s390/kvm_virtio.h | 10 ++++++++++
4 files changed, 34 insertions(+), 1 deletion(-)
Index: kvm/arch/s390/Kconfig
===================================================================
--- kvm.orig/arch/s390/Kconfig
+++ kvm/arch/s390/Kconfig
@@ -544,6 +544,7 @@ bool "s390 guest support (EXPERIMENTAL)"
depends on 64BIT && EXPERIMENTAL
select VIRTIO
select VIRTIO_RING
+ select VIRTIO_CONSOLE
help
Select this option if you want to run the kernel under s390 linux
endmenu
Index: kvm/arch/s390/kernel/setup.c
===================================================================
--- kvm.orig/arch/s390/kernel/setup.c
+++ kvm/arch/s390/kernel/setup.c
@@ -54,6 +54,7 @@
#include <asm/sections.h>
#include <asm/ebcdic.h>
#include <asm/compat.h>
+#include <asm/kvm_virtio.h>
long psw_kernel_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
@@ -799,7 +800,8 @@ setup_arch(char **cmdline_p)
printk("We are running under VM (64 bit mode)\n");
else if (MACHINE_IS_KVM) {
printk("We are running under KVM (64 bit mode)\n");
- add_preferred_console("ttyS", 1, NULL);
+ add_preferred_console("hvc", 0, NULL);
+ s390_virtio_console_init();
} else
printk("We are running native (64 bit mode)\n");
#endif /* CONFIG_64BIT */
Index: kvm/drivers/s390/kvm/kvm_virtio.c
===================================================================
--- kvm.orig/drivers/s390/kvm/kvm_virtio.c
+++ kvm/drivers/s390/kvm/kvm_virtio.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
+#include <linux/virtio_console.h>
#include <linux/interrupt.h>
#include <linux/virtio_ring.h>
#include <linux/pfn.h>
@@ -333,6 +334,25 @@ static int __init kvm_devices_init(void)
return 0;
}
+/* code for early console output with virtio_console */
+static __init int early_put_chars(u32 vtermno, const char *buf, int count)
+{
+ char scratch[17];
+ unsigned int len = count;
+
+ if (len > sizeof(scratch) - 1)
+ len = sizeof(scratch) - 1;
+ scratch[len] = '\0';
+ memcpy(scratch, buf, len);
+ kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, __pa(scratch));
+ return len;
+}
+
+void s390_virtio_console_init(void)
+{
+ virtio_cons_early_init(early_put_chars);
+}
+
/*
* We do this after core stuff, but before the drivers.
*/
Index: kvm/include/asm-s390/kvm_virtio.h
===================================================================
--- kvm.orig/include/asm-s390/kvm_virtio.h
+++ kvm/include/asm-s390/kvm_virtio.h
@@ -50,4 +50,14 @@ struct kvm_vqconfig {
#define KVM_S390_VIRTIO_RESET 1
#define KVM_S390_VIRTIO_SET_STATUS 2
+#ifdef __KERNEL__
+/* early virtio console setup */
+#ifdef CONFIG_VIRTIO_CONSOLE
+extern void s390_virtio_console_init(void);
+#else
+static inline void s390_virtio_console_init(void)
+{
+}
+#endif /* CONFIG_VIRTIO_CONSOLE */
+#endif /* __KERNEL__ */
#endif
^ permalink raw reply [flat|nested] 24+ messages in thread