diff mbox

[3/4] sparc64: convert spinlock_t to raw_spinlock_t in mmu_context_t

Message ID 20140304.141003.1969905483115684548.davem@davemloft.net
State RFC
Delegated to: David Miller
Headers show

Commit Message

David Miller March 4, 2014, 7:10 p.m. UTC
From: Kirill Tkhai <tkhai@yandex.ru>
Date: Fri, 28 Feb 2014 18:51:23 +0400

> This should be fixed like that's done for 8250
> [patch drivers-serial-cleanup-locking-for-rt.patch]

Like the patch below?

Is this transformation legitimate outside of the -rt tree?  I wish the commit
messages for the 8250 change was more verbose, explaining exactly why this
is needed.

And if it's needed, all the sparc serial/console drivers need this too.

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Kirill Tkhai March 4, 2014, 8:39 p.m. UTC | #1
Hi, David!

On 04.03.2014 23:10, David Miller wrote:
> From: Kirill Tkhai <tkhai@yandex.ru>
> Date: Fri, 28 Feb 2014 18:51:23 +0400
> 
>> This should be fixed like that's done for 8250
>> [patch drivers-serial-cleanup-locking-for-rt.patch]
> 
> Like the patch below?

Exactly this.

> Is this transformation legitimate outside of the -rt tree?  I wish the commit
> messages for the 8250 change was more verbose, explaining exactly why this
> is needed.
> 
> And if it's needed, all the sparc serial/console drivers need this too.

port->lock is mutex, so we should not disable interrupts before we are
doing spin_lock(). In RT spin_trylock_irqsave() does not disable irqs.

The patch is made to be good for both RT and !RT cases, so everything
is ok!

Really I don't know, why the original patch is not in upstream
***shrugging***. It's from 2009, everything is possible.


> diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c
> index cf86e72..dc697ce 100644
> --- a/drivers/tty/serial/sunhv.c
> +++ b/drivers/tty/serial/sunhv.c
> @@ -433,13 +433,10 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign
>  	unsigned long flags;
>  	int locked = 1;
>  
> -	local_irq_save(flags);
> -	if (port->sysrq) {
> -		locked = 0;
> -	} else if (oops_in_progress) {
> -		locked = spin_trylock(&port->lock);
> -	} else
> -		spin_lock(&port->lock);
> +	if (port->sysrq || oops_in_progress)
> +		locked = spin_trylock_irqsave(&port->lock, flags);
> +	else
> +		spin_lock_irqsave(&port->lock, flags);
>  
>  	while (n > 0) {
>  		unsigned long ra = __pa(con_write_page);
> @@ -470,8 +467,7 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign
>  	}
>  
>  	if (locked)
> -		spin_unlock(&port->lock);
> -	local_irq_restore(flags);
> +		spin_unlock_irqrestore(&port->lock, flags);
>  }
>  
>  static inline void sunhv_console_putchar(struct uart_port *port, char c)
> @@ -492,7 +488,10 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
>  	unsigned long flags;
>  	int i, locked = 1;
>  
> -	local_irq_save(flags);
> +	if (port->sysrq || oops_in_progress)
> +		locked = spin_trylock_irqsave(&port->lock, flags);
> +	else
> +		spin_lock_irqsave(&port->lock, flags);
>  	if (port->sysrq) {
>  		locked = 0;
>  	} else if (oops_in_progress) {
> @@ -507,8 +506,7 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
>  	}
>  
>  	if (locked)
> -		spin_unlock(&port->lock);
> -	local_irq_restore(flags);
> +		spin_unlock_irqrestore(&port->lock, flags);
>  }
>  
>  static struct console sunhv_console = {
> 

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sebastian Andrzej Siewior March 7, 2014, 1:41 p.m. UTC | #2
* David Miller | 2014-03-04 14:10:03 [-0500]:

>> This should be fixed like that's done for 8250
>> [patch drivers-serial-cleanup-locking-for-rt.patch]
>
>Like the patch below?

The patch looks good.

>Is this transformation legitimate outside of the -rt tree?  I wish the commit
>messages for the 8250 change was more verbose, explaining exactly why this
>is needed.

Looking at it, it looks like the transformation is legitimate in
vanila, too.

In -RT the spin_lock_irqsave() does not spin but sleep if the lock is
taken. Before that, local_irq_save() is invoked which disables
interrupts even on -RT. That is why you might_sleep() triggers a warning
here.
In the ->sysrq and oops_in_progress case it is save to trylock the lock
i.e. this is what we do now anyway except for ->sysrq where we assume
that the lock is already taken.

The spin_lock_irqsave() grabs the lock and disables the interrupts on
vanila (the same behavior) and on -RT it won't disable interrupts.

>And if it's needed, all the sparc serial/console drivers need this too.

Let me forward the 8250 to GregKH and see how he reacts. Would be nice
if it is another patch that gets removed from that queue…

Sebastian
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c
index cf86e72..dc697ce 100644
--- a/drivers/tty/serial/sunhv.c
+++ b/drivers/tty/serial/sunhv.c
@@ -433,13 +433,10 @@  static void sunhv_console_write_paged(struct console *con, const char *s, unsign
 	unsigned long flags;
 	int locked = 1;
 
-	local_irq_save(flags);
-	if (port->sysrq) {
-		locked = 0;
-	} else if (oops_in_progress) {
-		locked = spin_trylock(&port->lock);
-	} else
-		spin_lock(&port->lock);
+	if (port->sysrq || oops_in_progress)
+		locked = spin_trylock_irqsave(&port->lock, flags);
+	else
+		spin_lock_irqsave(&port->lock, flags);
 
 	while (n > 0) {
 		unsigned long ra = __pa(con_write_page);
@@ -470,8 +467,7 @@  static void sunhv_console_write_paged(struct console *con, const char *s, unsign
 	}
 
 	if (locked)
-		spin_unlock(&port->lock);
-	local_irq_restore(flags);
+		spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static inline void sunhv_console_putchar(struct uart_port *port, char c)
@@ -492,7 +488,10 @@  static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
 	unsigned long flags;
 	int i, locked = 1;
 
-	local_irq_save(flags);
+	if (port->sysrq || oops_in_progress)
+		locked = spin_trylock_irqsave(&port->lock, flags);
+	else
+		spin_lock_irqsave(&port->lock, flags);
 	if (port->sysrq) {
 		locked = 0;
 	} else if (oops_in_progress) {
@@ -507,8 +506,7 @@  static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
 	}
 
 	if (locked)
-		spin_unlock(&port->lock);
-	local_irq_restore(flags);
+		spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static struct console sunhv_console = {