* Re: Extending virtio_console to support multiple ports
[not found] ` <20090826112718.GA11117@amit-x200.redhat.com>
@ 2009-08-26 15:45 ` Amit Shah
2009-08-27 4:07 ` Benjamin Herrenschmidt
2009-08-27 5:04 ` Michael Ellerman
0 siblings, 2 replies; 10+ messages in thread
From: Amit Shah @ 2009-08-26 15:45 UTC (permalink / raw)
To: qemu-devel, kvm, virtualization
Cc: borntraeger, linux-kernel, miltonm, linuxppc-dev, brueckner, alan
[cc'ing some people who have made some commits in hvc_console.c]
On (Wed) Aug 26 2009 [16:57:18], Amit Shah wrote:
> On (Tue) Aug 25 2009 [11:47:20], Amit Shah wrote:
> >
> > Hello all,
> >
> > Here is a new iteration of the patch series that implements a
> > transport for guest and host communications.
> >
> > The code has been updated to reuse the virtio-console device instead
> > of creating a new virtio-serial device.
>
> And the problem now is that hvc calls the put_chars function with
> spinlocks held and we now allocate pages in send_buf(), called from
> put_chars.
>
> A few solutions:
[snip]
> - Convert hvc's usage of spinlocks to mutexes. I've no idea how this
> will play out; I'm no expert here. But I did try doing this and so far
> it all looks OK. No lockups, lockdep warnings, nothing. I have full
> debugging enabled. But this doesn't mean it's right.
So just to test this further I added the capability to have more than
one hvc console spawn from virtio_console, created two consoles and did
a 'cat' of a file in each of the virtio-consoles. It's been running for
half an hour now without any badness. No spew in debug logs too.
I also checked the code in hvc_console.c that takes the spin_locks.
Nothing there that runs from (or needs to run from) interrupt context.
So the change to mutexes does seem reasonable. Also, the spinlock code
was added really long back -- git blame shows Linus' first git commit
introduced them in the git history, so it's pure legacy baggage.
Also found a bug: hvc_resize() wants to be called with a lock held
(hp->lock) but virtio_console just calls it directly.
Anyway I'm wondering whether all those locks are needed.
Amit
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index d97779e..51078a3 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -35,7 +35,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/sched.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/freezer.h>
@@ -81,7 +81,7 @@ static LIST_HEAD(hvc_structs);
* Protect the list of hvc_struct instances from inserts and removals during
* list traversal.
*/
-static DEFINE_SPINLOCK(hvc_structs_lock);
+static DEFINE_MUTEX(hvc_structs_lock);
/*
* This value is used to assign a tty->index value to a hvc_struct based
@@ -98,23 +98,22 @@ static int last_hvc = -1;
static struct hvc_struct *hvc_get_by_index(int index)
{
struct hvc_struct *hp;
- unsigned long flags;
- spin_lock(&hvc_structs_lock);
+ mutex_lock(&hvc_structs_lock);
list_for_each_entry(hp, &hvc_structs, next) {
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
if (hp->index == index) {
kref_get(&hp->kref);
- spin_unlock_irqrestore(&hp->lock, flags);
- spin_unlock(&hvc_structs_lock);
+ mutex_unlock(&hp->lock);
+ mutex_unlock(&hvc_structs_lock);
return hp;
}
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
}
hp = NULL;
- spin_unlock(&hvc_structs_lock);
+ mutex_unlock(&hvc_structs_lock);
return hp;
}
@@ -228,15 +227,14 @@ console_initcall(hvc_console_init);
static void destroy_hvc_struct(struct kref *kref)
{
struct hvc_struct *hp = container_of(kref, struct hvc_struct, kref);
- unsigned long flags;
- spin_lock(&hvc_structs_lock);
+ mutex_lock(&hvc_structs_lock);
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
list_del(&(hp->next));
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
- spin_unlock(&hvc_structs_lock);
+ mutex_unlock(&hvc_structs_lock);
kfree(hp);
}
@@ -302,17 +300,16 @@ static void hvc_unthrottle(struct tty_struct *tty)
static int hvc_open(struct tty_struct *tty, struct file * filp)
{
struct hvc_struct *hp;
- unsigned long flags;
int rc = 0;
/* Auto increments kref reference if found. */
if (!(hp = hvc_get_by_index(tty->index)))
return -ENODEV;
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
/* Check and then increment for fast path open. */
if (hp->count++ > 0) {
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
hvc_kick();
return 0;
} /* else count == 0 */
@@ -321,7 +318,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
hp->tty = tty;
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
if (hp->ops->notifier_add)
rc = hp->ops->notifier_add(hp, hp->data);
@@ -333,9 +330,9 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
* tty fields and return the kref reference.
*/
if (rc) {
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
hp->tty = NULL;
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
tty->driver_data = NULL;
kref_put(&hp->kref, destroy_hvc_struct);
printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -349,7 +346,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
static void hvc_close(struct tty_struct *tty, struct file * filp)
{
struct hvc_struct *hp;
- unsigned long flags;
if (tty_hung_up_p(filp))
return;
@@ -363,12 +359,12 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
return;
hp = tty->driver_data;
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
if (--hp->count == 0) {
/* We are done with the tty pointer now. */
hp->tty = NULL;
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
if (hp->ops->notifier_del)
hp->ops->notifier_del(hp, hp->data);
@@ -386,7 +382,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
if (hp->count < 0)
printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
hp->vtermno, hp->count);
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
}
kref_put(&hp->kref, destroy_hvc_struct);
@@ -395,7 +391,6 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
static void hvc_hangup(struct tty_struct *tty)
{
struct hvc_struct *hp = tty->driver_data;
- unsigned long flags;
int temp_open_count;
if (!hp)
@@ -404,7 +399,7 @@ static void hvc_hangup(struct tty_struct *tty)
/* cancel pending tty resize work */
cancel_work_sync(&hp->tty_resize);
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
/*
* The N_TTY line discipline has problems such that in a close vs
@@ -412,7 +407,7 @@ static void hvc_hangup(struct tty_struct *tty)
* that from happening for now.
*/
if (hp->count <= 0) {
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
return;
}
@@ -421,7 +416,7 @@ static void hvc_hangup(struct tty_struct *tty)
hp->n_outbuf = 0;
hp->tty = NULL;
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
if (hp->ops->notifier_hangup)
hp->ops->notifier_hangup(hp, hp->data);
@@ -462,7 +457,6 @@ static int hvc_push(struct hvc_struct *hp)
static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
struct hvc_struct *hp = tty->driver_data;
- unsigned long flags;
int rsize, written = 0;
/* This write was probably executed during a tty close. */
@@ -472,7 +466,7 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
if (hp->count <= 0)
return -EIO;
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
/* Push pending writes */
if (hp->n_outbuf > 0)
@@ -488,7 +482,7 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
written += rsize;
hvc_push(hp);
}
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
/*
* Racy, but harmless, kick thread if there is still pending data.
@@ -511,7 +505,6 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
static void hvc_set_winsz(struct work_struct *work)
{
struct hvc_struct *hp;
- unsigned long hvc_flags;
struct tty_struct *tty;
struct winsize ws;
@@ -519,14 +512,14 @@ static void hvc_set_winsz(struct work_struct *work)
if (!hp)
return;
- spin_lock_irqsave(&hp->lock, hvc_flags);
+ mutex_lock(&hp->lock);
if (!hp->tty) {
- spin_unlock_irqrestore(&hp->lock, hvc_flags);
+ mutex_unlock(&hp->lock);
return;
}
ws = hp->ws;
tty = tty_kref_get(hp->tty);
- spin_unlock_irqrestore(&hp->lock, hvc_flags);
+ mutex_unlock(&hp->lock);
tty_do_resize(tty, &ws);
tty_kref_put(tty);
@@ -576,11 +569,10 @@ int hvc_poll(struct hvc_struct *hp)
struct tty_struct *tty;
int i, n, poll_mask = 0;
char buf[N_INBUF] __ALIGNED__;
- unsigned long flags;
int read_total = 0;
int written_total = 0;
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
/* Push pending writes */
if (hp->n_outbuf > 0)
@@ -622,9 +614,9 @@ int hvc_poll(struct hvc_struct *hp)
if (n <= 0) {
/* Hangup the tty when disconnected from host */
if (n == -EPIPE) {
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
tty_hangup(tty);
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
} else if ( n == -EAGAIN ) {
/*
* Some back-ends can only ensure a certain min
@@ -665,7 +657,7 @@ int hvc_poll(struct hvc_struct *hp)
tty_wakeup(tty);
}
bail:
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
if (read_total) {
/* Activity is occurring, so reset the polling backoff value to
@@ -714,11 +706,11 @@ static int khvcd(void *unused)
try_to_freeze();
wmb();
if (!cpus_are_in_xmon()) {
- spin_lock(&hvc_structs_lock);
+ mutex_lock(&hvc_structs_lock);
list_for_each_entry(hp, &hvc_structs, next) {
poll_mask |= hvc_poll(hp);
}
- spin_unlock(&hvc_structs_lock);
+ mutex_unlock(&hvc_structs_lock);
} else
poll_mask |= HVC_POLL_READ;
if (hvc_kicked)
@@ -777,8 +769,8 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
kref_init(&hp->kref);
INIT_WORK(&hp->tty_resize, hvc_set_winsz);
- spin_lock_init(&hp->lock);
- spin_lock(&hvc_structs_lock);
+ mutex_init(&hp->lock);
+ mutex_lock(&hvc_structs_lock);
/*
* find index to use:
@@ -796,7 +788,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
hp->index = i;
list_add_tail(&(hp->next), &hvc_structs);
- spin_unlock(&hvc_structs_lock);
+ mutex_unlock(&hvc_structs_lock);
return hp;
}
@@ -804,10 +796,9 @@ EXPORT_SYMBOL_GPL(hvc_alloc);
int hvc_remove(struct hvc_struct *hp)
{
- unsigned long flags;
struct tty_struct *tty;
- spin_lock_irqsave(&hp->lock, flags);
+ mutex_lock(&hp->lock);
tty = hp->tty;
if (hp->index < MAX_NR_HVC_CONSOLES)
@@ -815,7 +806,7 @@ int hvc_remove(struct hvc_struct *hp)
/* Don't whack hp->irq because tty_hangup() will need to free the irq. */
- spin_unlock_irqrestore(&hp->lock, flags);
+ mutex_unlock(&hp->lock);
/*
* We 'put' the instance that was grabbed when the kref instance
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h
index 3c85d78..3c086f8 100644
--- a/drivers/char/hvc_console.h
+++ b/drivers/char/hvc_console.h
@@ -45,7 +45,7 @@
#define HVC_ALLOC_TTY_ADAPTERS 8
struct hvc_struct {
- spinlock_t lock;
+ struct mutex lock;
int index;
struct tty_struct *tty;
int count;
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: Extending virtio_console to support multiple ports
2009-08-26 15:45 ` Extending virtio_console to support multiple ports Amit Shah
@ 2009-08-27 4:07 ` Benjamin Herrenschmidt
2009-08-27 6:51 ` [Qemu-devel] " Amit Shah
2009-08-27 9:08 ` Alan Cox
2009-08-27 5:04 ` Michael Ellerman
1 sibling, 2 replies; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2009-08-27 4:07 UTC (permalink / raw)
To: Amit Shah
Cc: kvm, linuxppc-dev, linux-kernel, miltonm, qemu-devel, borntraeger,
brueckner, virtualization, alan
On Wed, 2009-08-26 at 21:15 +0530, Amit Shah wrote:
>
> > - Convert hvc's usage of spinlocks to mutexes. I've no idea how this
> > will play out; I'm no expert here. But I did try doing this and so far
> > it all looks OK. No lockups, lockdep warnings, nothing. I have full
> > debugging enabled. But this doesn't mean it's right.
>
> So just to test this further I added the capability to have more than
> one hvc console spawn from virtio_console, created two consoles and did
> a 'cat' of a file in each of the virtio-consoles. It's been running for
> half an hour now without any badness. No spew in debug logs too.
>
> I also checked the code in hvc_console.c that takes the spin_locks.
> Nothing there that runs from (or needs to run from) interrupt context.
> So the change to mutexes does seem reasonable. Also, the spinlock code
> was added really long back -- git blame shows Linus' first git commit
> introduced them in the git history, so it's pure legacy baggage.
Two things here:
- First you seem to have completely missed the fact that hvc_poll() can
be called from interrupt time :-) Look at hvc_irq.c which is used by
some backends. Maybe that can be "fixed" by deferring to a work queue,
though it's nice to have the keyboard input have somewhat of a higher
priority than anything else here.
So unless that's fixed, or I missed something, that's a big NACK for
now.
- Then, are we certain that there's no case where the tty layer will
call us with some lock held or in an atomic context ? To be honest, I've
totally lost track of the locking rules in tty land lately so it might
well be ok, but something to verify.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Extending virtio_console to support multiple ports
2009-08-26 15:45 ` Extending virtio_console to support multiple ports Amit Shah
2009-08-27 4:07 ` Benjamin Herrenschmidt
@ 2009-08-27 5:04 ` Michael Ellerman
2009-08-27 6:52 ` Amit Shah
1 sibling, 1 reply; 10+ messages in thread
From: Michael Ellerman @ 2009-08-27 5:04 UTC (permalink / raw)
To: Amit Shah
Cc: kvm, linuxppc-dev, linux-kernel, miltonm, qemu-devel, borntraeger,
brueckner, virtualization, alan
[-- Attachment #1: Type: text/plain, Size: 1897 bytes --]
On Wed, 2009-08-26 at 21:15 +0530, Amit Shah wrote:
> [cc'ing some people who have made some commits in hvc_console.c]
>
> On (Wed) Aug 26 2009 [16:57:18], Amit Shah wrote:
> > On (Tue) Aug 25 2009 [11:47:20], Amit Shah wrote:
> > >
> > > Hello all,
> > >
> > > Here is a new iteration of the patch series that implements a
> > > transport for guest and host communications.
> > >
> > > The code has been updated to reuse the virtio-console device instead
> > > of creating a new virtio-serial device.
> >
> > And the problem now is that hvc calls the put_chars function with
> > spinlocks held and we now allocate pages in send_buf(), called from
> > put_chars.
> >
> > A few solutions:
>
> [snip]
>
> > - Convert hvc's usage of spinlocks to mutexes. I've no idea how this
> > will play out; I'm no expert here. But I did try doing this and so far
> > it all looks OK. No lockups, lockdep warnings, nothing. I have full
> > debugging enabled. But this doesn't mean it's right.
>
> So just to test this further I added the capability to have more than
> one hvc console spawn from virtio_console, created two consoles and did
> a 'cat' of a file in each of the virtio-consoles. It's been running for
> half an hour now without any badness. No spew in debug logs too.
>
> I also checked the code in hvc_console.c that takes the spin_locks.
> Nothing there that runs from (or needs to run from) interrupt context.
> So the change to mutexes does seem reasonable. Also, the spinlock code
> was added really long back -- git blame shows Linus' first git commit
> introduced them in the git history, so it's pure legacy baggage.
I won't tell Ryan you called his code "pure legacy baggage" if you
don't ;)
http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commitdiff;h=d450b4ae023fb4be175389c18f4f87677da03020
cheers
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] Re: Extending virtio_console to support multiple ports
2009-08-27 4:07 ` Benjamin Herrenschmidt
@ 2009-08-27 6:51 ` Amit Shah
2009-08-27 9:08 ` Alan Cox
1 sibling, 0 replies; 10+ messages in thread
From: Amit Shah @ 2009-08-27 6:51 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: kvm, borntraeger, qemu-devel, miltonm, linux-kernel, linuxppc-dev,
brueckner, virtualization, alan
On (Thu) Aug 27 2009 [14:07:03], Benjamin Herrenschmidt wrote:
> On Wed, 2009-08-26 at 21:15 +0530, Amit Shah wrote:
>
> >
> > > - Convert hvc's usage of spinlocks to mutexes. I've no idea how this
> > > will play out; I'm no expert here. But I did try doing this and so far
> > > it all looks OK. No lockups, lockdep warnings, nothing. I have full
> > > debugging enabled. But this doesn't mean it's right.
> >
> > So just to test this further I added the capability to have more than
> > one hvc console spawn from virtio_console, created two consoles and did
> > a 'cat' of a file in each of the virtio-consoles. It's been running for
> > half an hour now without any badness. No spew in debug logs too.
> >
> > I also checked the code in hvc_console.c that takes the spin_locks.
> > Nothing there that runs from (or needs to run from) interrupt context.
> > So the change to mutexes does seem reasonable. Also, the spinlock code
> > was added really long back -- git blame shows Linus' first git commit
> > introduced them in the git history, so it's pure legacy baggage.
>
> Two things here:
>
> - First you seem to have completely missed the fact that hvc_poll() can
> be called from interrupt time :-) Look at hvc_irq.c which is used by
Right! That's the obvious one.
> some backends. Maybe that can be "fixed" by deferring to a work queue,
> though it's nice to have the keyboard input have somewhat of a higher
> priority than anything else here.
Hm, to maintain the current behaviour of poll() returning some
poll_mask, the poll_mask could be made into an atomic variable with
khvcd() updating it. But to have read at a higher priority than the
other stuff, I don't quite see yet how that can be done.
> So unless that's fixed, or I missed something, that's a big NACK for
> now.
>
> - Then, are we certain that there's no case where the tty layer will
> call us with some lock held or in an atomic context ? To be honest, I've
The other routines are open(), close(), write(), etc., and other kernel
context (hvc_instantiate() and the khvcd thread).
> totally lost track of the locking rules in tty land lately so it might
> well be ok, but something to verify.
Yes.
Thanks for the response!
Amit
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Extending virtio_console to support multiple ports
2009-08-27 5:04 ` Michael Ellerman
@ 2009-08-27 6:52 ` Amit Shah
2009-08-27 14:13 ` Ryan Arnold
0 siblings, 1 reply; 10+ messages in thread
From: Amit Shah @ 2009-08-27 6:52 UTC (permalink / raw)
To: Michael Ellerman
Cc: kvm, linuxppc-dev, linux-kernel, miltonm, qemu-devel, borntraeger,
brueckner, virtualization, alan
On (Thu) Aug 27 2009 [15:04:45], Michael Ellerman wrote:
> On Wed, 2009-08-26 at 21:15 +0530, Amit Shah wrote:
> > [cc'ing some people who have made some commits in hvc_console.c]
> >
> > On (Wed) Aug 26 2009 [16:57:18], Amit Shah wrote:
> > > On (Tue) Aug 25 2009 [11:47:20], Amit Shah wrote:
> > > >
> > > > Hello all,
> > > >
> > > > Here is a new iteration of the patch series that implements a
> > > > transport for guest and host communications.
> > > >
> > > > The code has been updated to reuse the virtio-console device instead
> > > > of creating a new virtio-serial device.
> > >
> > > And the problem now is that hvc calls the put_chars function with
> > > spinlocks held and we now allocate pages in send_buf(), called from
> > > put_chars.
> > >
> > > A few solutions:
> >
> > [snip]
> >
> > > - Convert hvc's usage of spinlocks to mutexes. I've no idea how this
> > > will play out; I'm no expert here. But I did try doing this and so far
> > > it all looks OK. No lockups, lockdep warnings, nothing. I have full
> > > debugging enabled. But this doesn't mean it's right.
> >
> > So just to test this further I added the capability to have more than
> > one hvc console spawn from virtio_console, created two consoles and did
> > a 'cat' of a file in each of the virtio-consoles. It's been running for
> > half an hour now without any badness. No spew in debug logs too.
> >
> > I also checked the code in hvc_console.c that takes the spin_locks.
> > Nothing there that runs from (or needs to run from) interrupt context.
> > So the change to mutexes does seem reasonable. Also, the spinlock code
> > was added really long back -- git blame shows Linus' first git commit
> > introduced them in the git history, so it's pure legacy baggage.
>
> I won't tell Ryan you called his code "pure legacy baggage" if you
> don't ;)
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commitdiff;h=d450b4ae023fb4be175389c18f4f87677da03020
Thanks for the link!
(and this general area might be the one that doesn't get major upheavals
in 5-yr spans :-)
Amit
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Extending virtio_console to support multiple ports
2009-08-27 4:07 ` Benjamin Herrenschmidt
2009-08-27 6:51 ` [Qemu-devel] " Amit Shah
@ 2009-08-27 9:08 ` Alan Cox
2009-08-27 9:27 ` Benjamin Herrenschmidt
2009-08-29 1:15 ` [Qemu-devel] Re: Extending virtio_console to support multiple ports Jamie Lokier
1 sibling, 2 replies; 10+ messages in thread
From: Alan Cox @ 2009-08-27 9:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: kvm, linuxppc-dev, linux-kernel, miltonm, qemu-devel, borntraeger,
brueckner, Amit Shah, virtualization
> - Then, are we certain that there's no case where the tty layer will
> call us with some lock held or in an atomic context ? To be honest,
> I've totally lost track of the locking rules in tty land lately so it
> might well be ok, but something to verify.
Some of the less well behaved line disciplines do this and always have
done.
Alan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Extending virtio_console to support multiple ports
2009-08-27 9:08 ` Alan Cox
@ 2009-08-27 9:27 ` Benjamin Herrenschmidt
2009-08-27 11:45 ` [PATCH] hvc_console: provide (un)locked version for hvc_resize() Hendrik Brueckner
2009-08-29 1:15 ` [Qemu-devel] Re: Extending virtio_console to support multiple ports Jamie Lokier
1 sibling, 1 reply; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2009-08-27 9:27 UTC (permalink / raw)
To: Alan Cox
Cc: kvm, linuxppc-dev, linux-kernel, miltonm, qemu-devel, borntraeger,
brueckner, Amit Shah, virtualization
On Thu, 2009-08-27 at 10:08 +0100, Alan Cox wrote:
> > - Then, are we certain that there's no case where the tty layer will
> > call us with some lock held or in an atomic context ? To be honest,
> > I've totally lost track of the locking rules in tty land lately so it
> > might well be ok, but something to verify.
>
> Some of the less well behaved line disciplines do this and always have
> done.
That was also my understanding but heh, I though that maybe you may have
fixed all of that already :-)
So at this stage, I think the reasonably thing to do is to stick to the
spinlock, but we can try to make it a bit smarter, and we can definitely
attempt to fix the case Amit pointed out where we call resize without a
lock while it seems to expect it (though we also need to be careful
about re-entrancy I believe).
Cheers,
Ben.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] hvc_console: provide (un)locked version for hvc_resize()
2009-08-27 9:27 ` Benjamin Herrenschmidt
@ 2009-08-27 11:45 ` Hendrik Brueckner
0 siblings, 0 replies; 10+ messages in thread
From: Hendrik Brueckner @ 2009-08-27 11:45 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Carsten Otte, kvm, linuxppc-dev, linux-kernel, Heiko Carstens,
qemu-devel, miltonm, virtualization, borntraeger, brueckner,
Amit Shah, Martin Schwidefsky, Alan Cox
On Thu, Aug 27, 2009 at 07:27:23PM +1000, Benjamin Herrenschmidt wrote:
> On Thu, 2009-08-27 at 10:08 +0100, Alan Cox wrote:
> So at this stage, I think the reasonably thing to do is to stick to the
> spinlock, but we can try to make it a bit smarter, and we can definitely
> attempt to fix the case Amit pointed out where we call resize without a
> lock while it seems to expect it (though we also need to be careful
> about re-entrancy I believe).
I have worked on a patch for providing a locked hvc_resize() function.
Since only two back-ends (virtio_console and hvc_iucv) use the function,
I decided to update my hvc_iucv back-end through renaming the function
call as follows:
Rename the locking free hvc_resize() function to __hvc_resize() and
provide an inline function that locks the hvc_struct and calls
__hvc_resize().
The rationale for this patch is that virtio_console calls the hvc_resize()
function without locking the hvc_struct.
According to naming rules, the unlocked version is renamed and
prefixed with "__".
References to unlocked function calls in hvc back-ends has been updated.
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
drivers/char/hvc_console.c | 6 +++---
drivers/char/hvc_console.h | 12 +++++++++++-
drivers/char/hvc_iucv.c | 4 +++-
3 files changed, 17 insertions(+), 5 deletions(-)
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -680,7 +680,7 @@ int hvc_poll(struct hvc_struct *hp)
EXPORT_SYMBOL_GPL(hvc_poll);
/**
- * hvc_resize() - Update terminal window size information.
+ * __hvc_resize() - Update terminal window size information.
* @hp: HVC console pointer
* @ws: Terminal window size structure
*
@@ -689,12 +689,12 @@ EXPORT_SYMBOL_GPL(hvc_poll);
*
* Locking: Locking free; the function MUST be called holding hp->lock
*/
-void hvc_resize(struct hvc_struct *hp, struct winsize ws)
+void __hvc_resize(struct hvc_struct *hp, struct winsize ws)
{
hp->ws = ws;
schedule_work(&hp->tty_resize);
}
-EXPORT_SYMBOL_GPL(hvc_resize);
+EXPORT_SYMBOL_GPL(__hvc_resize);
/*
* This kthread is either polling or interrupt driven. This is determined by
--- a/drivers/char/hvc_console.h
+++ b/drivers/char/hvc_console.h
@@ -28,6 +28,7 @@
#define HVC_CONSOLE_H
#include <linux/kref.h>
#include <linux/tty.h>
+#include <linux/spinlock.h>
/*
* This is the max number of console adapters that can/will be found as
@@ -88,7 +89,16 @@ int hvc_poll(struct hvc_struct *hp);
void hvc_kick(void);
/* Resize hvc tty terminal window */
-extern void hvc_resize(struct hvc_struct *hp, struct winsize ws);
+extern void __hvc_resize(struct hvc_struct *hp, struct winsize ws);
+
+static inline void hvc_resize(struct hvc_struct *hp, struct winsize ws)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hp->lock, flags);
+ __hvc_resize(hp, ws);
+ spin_unlock_irqrestore(&hp->lock, flags);
+}
/* default notifier for irq based notification */
extern int notifier_add_irq(struct hvc_struct *hp, int data);
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -273,7 +273,9 @@ static int hvc_iucv_write(struct hvc_iuc
case MSG_TYPE_WINSIZE:
if (rb->mbuf->datalen != sizeof(struct winsize))
break;
- hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data));
+ /* The caller must ensure that the hvc is locked, which
+ * is the case when called from hvc_iucv_get_chars() */
+ __hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data));
break;
case MSG_TYPE_ERROR: /* ignored ... */
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Extending virtio_console to support multiple ports
2009-08-27 6:52 ` Amit Shah
@ 2009-08-27 14:13 ` Ryan Arnold
0 siblings, 0 replies; 10+ messages in thread
From: Ryan Arnold @ 2009-08-27 14:13 UTC (permalink / raw)
To: Amit Shah
Cc: kvm, linuxppc-dev, linux-kernel, miltonm, qemu-devel, borntraeger,
brueckner, virtualization, alan
On Thu, 2009-08-27 at 12:22 +0530, Amit Shah wrote:
> On (Thu) Aug 27 2009 [15:04:45], Michael Ellerman wrote:
> Ryan you called his code "pure legacy baggage" if you
> > don't ;)
> >
> > http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commitdiff;h=d450b4ae023fb4be175389c18f4f87677da03020
>
> Thanks for the link!
>
> (and this general area might be the one that doesn't get major upheavals
> in 5-yr spans :-)
Actually, quite the opposite... too many cooks in the kitchen in the
last 6 years have left this code with some historical oddities. When I
added the interrupt context code in the first place I made sure that the
driver did NOTHING in the interrupt handler except awaken the working
thread. Someone in the subsequent years thought it'd be a good idea to
have the interrupt handler actually do the work.
Furthermore the front and backends were separated so that new front ends
can be used. This was sometime in the last 5 years as well.
Let's just say I'm happy to pass the torch on this one.
I would suggest that someone perform throughput tests on this driver at
some point. At the point where I stopped maintaining it I'd gotten the
driver to the point where there was no jerking output or lost data under
heavy I/O load. I'm not sure where the driver's at now.
Ryan S. Arnold
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] Re: Extending virtio_console to support multiple ports
2009-08-27 9:08 ` Alan Cox
2009-08-27 9:27 ` Benjamin Herrenschmidt
@ 2009-08-29 1:15 ` Jamie Lokier
1 sibling, 0 replies; 10+ messages in thread
From: Jamie Lokier @ 2009-08-29 1:15 UTC (permalink / raw)
To: Alan Cox
Cc: kvm, borntraeger, qemu-devel, miltonm, linux-kernel, linuxppc-dev,
brueckner, Amit Shah, virtualization
Alan Cox wrote:
> > - Then, are we certain that there's no case where the tty layer will
> > call us with some lock held or in an atomic context ? To be honest,
> > I've totally lost track of the locking rules in tty land lately so it
> > might well be ok, but something to verify.
>
> Some of the less well behaved line disciplines do this and always have
> done.
I had a backtrace in my kernel log recently which looked like that,
while doing PPP over Bluetooth RFCOMM. Resulted in AppArmor
complaining that it's hook was being called in irq context.
-- Jamie
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-08-29 1:50 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1251181044-3696-1-git-send-email-amit.shah@redhat.com>
[not found] ` <20090826112718.GA11117@amit-x200.redhat.com>
2009-08-26 15:45 ` Extending virtio_console to support multiple ports Amit Shah
2009-08-27 4:07 ` Benjamin Herrenschmidt
2009-08-27 6:51 ` [Qemu-devel] " Amit Shah
2009-08-27 9:08 ` Alan Cox
2009-08-27 9:27 ` Benjamin Herrenschmidt
2009-08-27 11:45 ` [PATCH] hvc_console: provide (un)locked version for hvc_resize() Hendrik Brueckner
2009-08-29 1:15 ` [Qemu-devel] Re: Extending virtio_console to support multiple ports Jamie Lokier
2009-08-27 5:04 ` Michael Ellerman
2009-08-27 6:52 ` Amit Shah
2009-08-27 14:13 ` Ryan Arnold
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).