public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sergey Vlasov <vsu@altlinux.ru>
To: Jason Baron <jbaron@redhat.com>
Cc: Krzysztof Taraszka <dzimi@pld-linux.org>, linux-kernel@vger.kernel.org
Subject: [PATCH] Update termios to use per tty semaphore (backport from 2.6.x)
Date: Sun, 7 Nov 2004 23:10:15 +0300	[thread overview]
Message-ID: <20041107201015.GB2345@sirius.home> (raw)
In-Reply-To: <20041107200601.GA2345@sirius.home>

[-- Attachment #1: Type: text/plain, Size: 6398 bytes --]

This is a 2.4.x backport of the termios locking changes made in 2.6.x:

#   2004/10/02 15:46:35-07:00 alan@lxorguk.ukuu.org.uk 
#   [PATCH] Update termios to use per tty semaphore
#   
#   This makes the agreed change of termios locking to be semaphore based
#   sleep locking. This is needed for USB in particular as it has to use
#   messaging to issue terminal mode changes.
#   
#   This code passes Torvalds test grades 0, 1 and 2 (it looks ok, it
#   compiles and it booted). It does mean that a driver cannot take an
#   atomic peek at termios data during an interrupt. Nobody seems to be
#   doing this although some of the driver receive paths for line
#   disciplines will eventually want to (n_tty currently doesn't do this
#   locked on the receive path). Since the ldisc is given a chance to copy
#   any essential bits on the ->set_termios path this seems not to be a
#   problem.

--- kernel-source-2.4.27/include/linux/tty.h.termios	2004-10-31 18:07:10 +0300
+++ kernel-source-2.4.27/include/linux/tty.h	2004-10-31 20:23:38 +0300
@@ -261,6 +261,7 @@ struct tty_struct {
 	int	magic;
 	struct tty_driver driver;
 	struct tty_ldisc ldisc;
+	struct semaphore termios_sem;
 	struct termios *termios, *termios_locked;
 	int pgrp;
 	int session;
--- kernel-source-2.4.27/drivers/char/tty_io.c.termios	2004-10-31 18:04:37 +0300
+++ kernel-source-2.4.27/drivers/char/tty_io.c	2004-10-31 20:26:13 +0300
@@ -118,8 +118,6 @@ extern void disable_early_printk(void);
 #define TTY_PARANOIA_CHECK 1
 #define CHECK_TTY_COUNT 1
 
-/* Lock for tty_termios changes - private to tty_io/tty_ioctl */
-spinlock_t tty_termios_lock = SPIN_LOCK_UNLOCKED;
 struct termios tty_std_termios;		/* for the benefit of tty drivers  */
 struct tty_driver *tty_drivers;		/* linked list of tty drivers */
 
@@ -269,10 +267,9 @@ static int check_tty_count(struct tty_st
 
 static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
 {
-	unsigned long flags;
-	spin_lock_irqsave(&tty_termios_lock, flags);
+	down(&tty->termios_sem);
 	tty->termios->c_line = num;
-	spin_unlock_irqrestore(&tty_termios_lock, flags);
+	up(&tty->termios_sem);
 }
 
 /*
@@ -803,10 +800,9 @@ void do_tty_hangup(void *data)
 
 	if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS)
 	{
-		unsigned long flags;
-		spin_lock_irqsave(&tty_termios_lock, flags);
+		down(&tty->termios_sem);
                 *tty->termios = tty->driver.init_termios;
-		spin_unlock_irqrestore(&tty_termios_lock, flags);
+		up(&tty->termios_sem);
 	}
 
 	/* Defer ldisc switch */
@@ -2452,6 +2448,7 @@ static void initialize_tty_struct(struct
 	tty->flip.tqueue.routine = flush_to_ldisc;
 	tty->flip.tqueue.data = tty;
 	init_MUTEX(&tty->flip.pty_sem);
+	init_MUTEX(&tty->termios_sem);
 	init_waitqueue_head(&tty->write_wait);
 	init_waitqueue_head(&tty->read_wait);
 	tty->tq_hangup.routine = do_tty_hangup;
--- kernel-source-2.4.27/drivers/char/tty_ioctl.c.termios	2004-10-31 18:04:37 +0300
+++ kernel-source-2.4.27/drivers/char/tty_ioctl.c	2004-10-31 20:31:47 +0300
@@ -29,8 +29,6 @@
 
 #undef	DEBUG
 
-extern spinlock_t tty_termios_lock;
-
 /*
  * Internal flag options for termios setting behavior
  */
@@ -99,7 +97,6 @@ static void change_termios(struct tty_st
 	int canon_change;
 	struct termios old_termios = *tty->termios;
 	struct tty_ldisc *ld;
-	unsigned long flags;
 
 	/*
 	 *      Perform the actual termios internal changes under lock.
@@ -107,7 +104,7 @@ static void change_termios(struct tty_st
 
 	/* FIXME: we need to decide on some locking/ordering semantics
 	   for the set_termios notification eventually */
-	spin_lock_irqsave(&tty_termios_lock, flags);
+	down(&tty->termios_sem);
 
 	*tty->termios = *new_termios;
 	unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
@@ -147,8 +144,7 @@ static void change_termios(struct tty_st
 			(ld->set_termios)(tty, &old_termios);
 		tty_ldisc_deref(ld);
 	}
-	spin_unlock_irqrestore(&tty_termios_lock, flags);
-
+	up(&tty->termios_sem);
 }
 
 static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
@@ -244,13 +240,13 @@ static int get_sgttyb(struct tty_struct 
 	struct sgttyb tmp;
 	unsigned long flags;
 
-	spin_lock_irqsave(&tty_termios_lock, flags);
+	down(&tty->termios_sem);
 	tmp.sg_ispeed = 0;
 	tmp.sg_ospeed = 0;
 	tmp.sg_erase = tty->termios->c_cc[VERASE];
 	tmp.sg_kill = tty->termios->c_cc[VKILL];
 	tmp.sg_flags = get_sgflags(tty);
-	spin_unlock_irqrestore(&tty_termios_lock, flags);
+	up(&tty->termios_sem);
 
 	return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
@@ -286,19 +282,18 @@ static int set_sgttyb(struct tty_struct 
 	int retval;
 	struct sgttyb tmp;
 	struct termios termios;
-	unsigned long flags;
 
 	retval = tty_check_change(tty);
 	if (retval)
 		return retval;
 	if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
 		return -EFAULT;
-	spin_lock_irqsave(&tty_termios_lock, flags);
+	down(&tty->termios_sem);
 	termios =  *tty->termios;
 	termios.c_cc[VERASE] = tmp.sg_erase;
 	termios.c_cc[VKILL] = tmp.sg_kill;
 	set_sgflags(&termios, tmp.sg_flags);
-	spin_unlock_irqrestore(&tty_termios_lock, flags);
+	up(&tty->termios_sem);
 	change_termios(tty, &termios);
 	return 0;
 }
@@ -533,11 +528,11 @@ int n_tty_ioctl(struct tty_struct * tty,
 		case TIOCSSOFTCAR:
 			if (get_user(arg, (unsigned int *) arg))
 				return -EFAULT;
-			spin_lock_irqsave(&tty_termios_lock, flags);
+			down(&tty->termios_sem);
 			tty->termios->c_cflag =
 				((tty->termios->c_cflag & ~CLOCAL) |
 				 (arg ? CLOCAL : 0));
-			spin_unlock_irqrestore(&tty_termios_lock, flags);
+			up(&tty->termios_sem);
 			return 0;
 		default:
 			return -ENOIOCTLCMD;
--- kernel-source-2.4.27/Documentation/tty.txt.termios	2004-10-31 18:04:36 +0300
+++ kernel-source-2.4.27/Documentation/tty.txt	2004-10-31 20:23:38 +0300
@@ -158,8 +158,8 @@ write_room()	-	Return the number of char
 
 ioctl()		-	Called when an ioctl may be for the driver
 
-set_termios()	-	Called on termios change, may get parallel calls,
-			may block for now (may change that)
+set_termios()	-	Called on termios change, serialized against
+			itself by a semaphore. May sleep.
 
 set_ldisc()	-	Notifier for discipline change. At the point this 
 			is done the discipline is not yet usable. Can now

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

  reply	other threads:[~2004-11-07 20:11 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-24 17:49 [Patch] 2.4.28-pre3 tty/ldisc fixes Jason Baron
2004-10-28 18:35 ` Sergey Vlasov
2004-10-28 18:42   ` Jason Baron
     [not found]   ` <Pine.LNX.4.44.0410291426240.13340-200000@dhcp83-105.boston.redhat.com>
2004-10-30 19:19     ` Sergey Vlasov
2004-10-31  9:53       ` Krzysztof Taraszka
2004-11-02 15:02         ` Jason Baron
2004-11-07 20:06           ` Sergey Vlasov
2004-11-07 20:10             ` Sergey Vlasov [this message]
2004-11-07 20:13             ` [PATCH] Add back lost call to tty->driver.set_termios Sergey Vlasov
2004-10-31 17:18       ` [Patch] 2.4.28-pre3 tty/ldisc fixes Sergey Vlasov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20041107201015.GB2345@sirius.home \
    --to=vsu@altlinux.ru \
    --cc=dzimi@pld-linux.org \
    --cc=jbaron@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox