mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@osdl.org>
To: "H. Peter Anvin" <hpa@zytor.com>
Cc: cloos@jhcloos.com, linux-kernel@vger.kernel.org
Subject: Re: something funny about tty's on 2.6.4-rc1-mm1
Date: Tue, 2 Mar 2004 14:08:09 -0800	[thread overview]
Message-ID: <20040302140809.6b0ef6f8.akpm@osdl.org> (raw)
In-Reply-To: <4044BC48.7060903@zytor.com>

"H. Peter Anvin" <hpa@zytor.com> wrote:
>
> > Will patching in the old behavior wrt re-use, while not disrupting
> > the other improvements, be a lot of work?  I've looked thru the src, 
> > but haven't yet spotted the point where the new pis number is chosen.
> 
> Not a lot of work, but the performance would suffer big time.

The (untested) first-fit patch I proposed uses a radix tree, so it should
in fact be faster than the old code.

Are you now thinking that we might need to change the pty allocator?



 drivers/char/tty_io.c |   50 ++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 40 insertions(+), 10 deletions(-)

diff -puN drivers/char/tty_io.c~pty-allocation-first-fit drivers/char/tty_io.c
--- 25/drivers/char/tty_io.c~pty-allocation-first-fit	2004-02-26 18:59:21.000000000 -0800
+++ 25-akpm/drivers/char/tty_io.c	2004-02-26 18:59:58.000000000 -0800
@@ -91,6 +91,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/device.h>
+#include <linux/idr.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -125,6 +126,8 @@ struct tty_ldisc ldiscs[NR_LDISCS];	/* l
 #ifdef CONFIG_UNIX98_PTYS
 extern struct tty_driver *ptm_driver;	/* Unix98 pty masters; for /dev/ptmx */
 extern int pty_limit;		/* Config limit on Unix98 ptys */
+static struct idr allocated_ptys;
+static DECLARE_MUTEX(allocated_ptys_lock);
 #endif
 
 extern void disable_early_printk(void);
@@ -1305,6 +1308,14 @@ static void release_dev(struct file * fi
 	 */
 	flush_scheduled_work();
 
+#ifdef CONFIG_UNIX98_PTYS
+	if (filp->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,2)) {
+		down(&allocated_ptys_lock);
+		idr_remove(&allocated_ptys, idx);
+		up(&allocated_ptys_lock);
+	}
+#endif
+
 	/* 
 	 * The release_mem function takes care of the details of clearing
 	 * the slots and preserving the termios structure.
@@ -1329,7 +1340,7 @@ static int tty_open(struct inode * inode
 	struct tty_struct *tty;
 	int noctty, retval;
 	struct tty_driver *driver;
-	int index;
+	int index = -1;
 	dev_t device = inode->i_rdev;
 	unsigned short saved_flags = filp->f_flags;
 retry_open:
@@ -1372,22 +1383,32 @@ retry_open:
 #ifdef CONFIG_UNIX98_PTYS
 	if (device == MKDEV(TTYAUX_MAJOR,2)) {
 		/* find a device that is not in use. */
-		static int next_ptmx_dev = 0;
-		retval = -1;
+		down(&allocated_ptys_lock);
+		if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) {
+			up(&allocated_ptys_lock);
+			return -ENOMEM;
+		}
+		index = idr_get_new(&allocated_ptys, NULL);
+		if (index >= pty_limit) {
+			idr_remove(&allocated_ptys, index);
+			up(&allocated_ptys_lock);
+			return -EIO;
+		}
 		driver = ptm_driver;
-		while (driver->refcount < pty_limit) {
-			index = next_ptmx_dev;
-			next_ptmx_dev = (next_ptmx_dev+1) % driver->num;
-			if (!init_dev(driver, index, &tty))
-				goto ptmx_found; /* ok! */
+		retval = init_dev(driver, index, &tty);
+		if (retval) {
+			idr_remove(&allocated_ptys, index);
+			up(&allocated_ptys_lock);
+			return retval;
 		}
-		return -EIO; /* no free ptys */
-	ptmx_found:
 		set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
 		if (devpts_pty_new(tty->link)) {
 			/* BADNESS - need to destroy both ptm and pts! */
+			idr_remove(&allocated_ptys, index);
+			up(&allocated_ptys_lock);
 			return -ENOMEM;
 		}
+		up(&allocated_ptys_lock);
 		noctty = 1;
 	} else
 #endif
@@ -1425,6 +1446,14 @@ got_driver:
 		       tty->name);
 #endif
 
+#ifdef CONFIG_UNIX98_PTYS
+		if (index != -1) {
+			down(&allocated_ptys_lock);
+			idr_remove(&allocated_ptys, index);
+			up(&allocated_ptys_lock);
+		}
+#endif
+
 		release_dev(filp);
 		if (retval != -ERESTARTSYS)
 			return retval;
@@ -2435,6 +2464,7 @@ static int __init tty_init(void)
 	kobject_register(&tty_kobj);
 
 #ifdef CONFIG_UNIX98_PTYS
+	idr_init(&allocated_ptys);
 	strcpy(ptmx_cdev.kobj.name, "dev.ptmx");
 	cdev_init(&ptmx_cdev, &tty_fops);
 	if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||

_


  reply	other threads:[~2004-03-02 22:07 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-01 18:45 Nuno Monteiro
2004-03-01 19:09 ` Richard B. Johnson
2004-03-02  5:47 ` H. Peter Anvin
2004-03-02 14:52   ` James H. Cloos Jr.
2004-03-02 15:02     ` Richard B. Johnson
2004-03-02 17:47       ` James H. Cloos Jr.
2004-03-02 16:54     ` H. Peter Anvin
2004-03-02 22:08       ` Andrew Morton [this message]
2004-03-03  2:29         ` H. Peter Anvin
2004-03-02 19:04 Albert Cahalan
2004-03-02 19:54 ` H. Peter Anvin
2004-03-02 22:46 ` Edgar Toernig
2004-03-02 23:59   ` H. Peter Anvin
2004-03-03  4:12 Albert Cahalan

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=20040302140809.6b0ef6f8.akpm@osdl.org \
    --to=akpm@osdl.org \
    --cc=cloos@jhcloos.com \
    --cc=hpa@zytor.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

all inboxes | Powered by JetHome®