Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d29f3ef3 authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman
Browse files

tty_lock: Localise the lock



In each remaining case the tty_lock is associated with a specific tty. This
means we can now lock on a per tty basis. We do need tty_lock_pair() for
the pty case. Uglier but still a step in the right direction.

[fixed up calls in 3 missing drivers - gregkh]

Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d739e65b
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -1859,9 +1859,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
		printk("block_til_ready blocking: ttys%d, count = %d\n",
		printk("block_til_ready blocking: ttys%d, count = %d\n",
		       info->line, state->count);
		       info->line, state->count);
#endif
#endif
		tty_unlock();
		tty_unlock(tty);
		schedule();
		schedule();
		tty_lock();
		tty_lock(tty);
	}
	}
	current->state = TASK_RUNNING;
	current->state = TASK_RUNNING;
	remove_wait_queue(&info->open_wait, &wait);
	remove_wait_queue(&info->open_wait, &wait);
+6 −6
Original line number Original line Diff line number Diff line
@@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
	if (!retinfo)
	if (!retinfo)
		return -EFAULT;
		return -EFAULT;
	memset(&tmp, 0, sizeof(tmp));
	memset(&tmp, 0, sizeof(tmp));
	tty_lock();
	tty_lock(tty);
	tmp.line = tty->index;
	tmp.line = tty->index;
	tmp.port = state->port;
	tmp.port = state->port;
	tmp.flags = state->tport.flags;
	tmp.flags = state->tport.flags;
@@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
	tmp.close_delay = state->tport.close_delay;
	tmp.close_delay = state->tport.close_delay;
	tmp.closing_wait = state->tport.closing_wait;
	tmp.closing_wait = state->tport.closing_wait;
	tmp.custom_divisor = state->custom_divisor;
	tmp.custom_divisor = state->custom_divisor;
	tty_unlock();
	tty_unlock(tty);
	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
@@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
		return -EFAULT;
		return -EFAULT;


	tty_lock();
	tty_lock(tty);
	change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
	change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
		new_serial.custom_divisor != state->custom_divisor;
		new_serial.custom_divisor != state->custom_divisor;
	if (new_serial.irq || new_serial.port != state->port ||
	if (new_serial.irq || new_serial.port != state->port ||
			new_serial.xmit_fifo_size != state->xmit_fifo_size) {
			new_serial.xmit_fifo_size != state->xmit_fifo_size) {
		tty_unlock();
		tty_unlock(tty);
		return -EINVAL;
		return -EINVAL;
	}
	}
  
  
@@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
	}
	}


	if (new_serial.baud_base < 9600) {
	if (new_serial.baud_base < 9600) {
		tty_unlock();
		tty_unlock(tty);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -1116,7 +1116,7 @@ check_and_exit:
		}
		}
	} else
	} else
		retval = startup(tty, state);
		retval = startup(tty, state);
	tty_unlock();
	tty_unlock(tty);
	return retval;
	return retval;
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
	 * If the port is the middle of closing, bail out now
	 * If the port is the middle of closing, bail out now
	 */
	 */
	if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
	if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
		wait_event_interruptible_tty(info->port.close_wait,
		wait_event_interruptible_tty(tty, info->port.close_wait,
				!(info->port.flags & ASYNC_CLOSING));
				!(info->port.flags & ASYNC_CLOSING));
		return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
		return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
	}
	}
+6 −5
Original line number Original line Diff line number Diff line
@@ -1065,7 +1065,8 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,


	TRACE_L("read()");
	TRACE_L("read()");


	tty_lock();
	/* FIXME: should use a private lock */
	tty_lock(tty);


	pClient = findClient(pInfo, task_pid(current));
	pClient = findClient(pInfo, task_pid(current));
	if (pClient) {
	if (pClient) {
@@ -1077,7 +1078,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
				goto unlock;
				goto unlock;
			}
			}
			/* block until there is a message: */
			/* block until there is a message: */
			wait_event_interruptible_tty(pInfo->read_wait,
			wait_event_interruptible_tty(tty, pInfo->read_wait,
					(pMsg = remove_msg(pInfo, pClient)));
					(pMsg = remove_msg(pInfo, pClient)));
		}
		}


@@ -1107,7 +1108,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
	}
	}
	ret = -EPERM;
	ret = -EPERM;
unlock:
unlock:
	tty_unlock();
	tty_unlock(tty);
	return ret;
	return ret;
}
}


@@ -1156,7 +1157,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
	pHeader->locks = 0;
	pHeader->locks = 0;
	pHeader->owner = NULL;
	pHeader->owner = NULL;


	tty_lock();
	tty_lock(tty);


	pClient = findClient(pInfo, task_pid(current));
	pClient = findClient(pInfo, task_pid(current));
	if (pClient) {
	if (pClient) {
@@ -1175,7 +1176,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
	add_tx_queue(pInfo, pHeader);
	add_tx_queue(pInfo, pHeader);
	trigger_transmit(pInfo);
	trigger_transmit(pInfo);


	tty_unlock();
	tty_unlock(tty);


	return 0;
	return 0;
}
}
+13 −10
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
	wake_up_interruptible(&tty->read_wait);
	wake_up_interruptible(&tty->read_wait);
	wake_up_interruptible(&tty->write_wait);
	wake_up_interruptible(&tty->write_wait);
	tty->packet = 0;
	tty->packet = 0;
	/* Review - krefs on tty_link ?? */
	if (!tty->link)
	if (!tty->link)
		return;
		return;
	tty->link->packet = 0;
	tty->link->packet = 0;
@@ -62,9 +63,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
		        mutex_unlock(&devpts_mutex);
		        mutex_unlock(&devpts_mutex);
		}
		}
#endif
#endif
		tty_unlock();
		tty_vhangup(tty->link);
		tty_vhangup(tty->link);
		tty_lock();
	}
	}
}
}


@@ -622,26 +621,29 @@ static int ptmx_open(struct inode *inode, struct file *filp)
		return retval;
		return retval;


	/* find a device that is not in use. */
	/* find a device that is not in use. */
	tty_lock();
	mutex_lock(&devpts_mutex);
	index = devpts_new_index(inode);
	index = devpts_new_index(inode);
	tty_unlock();
	if (index < 0) {
	if (index < 0) {
		retval = index;
		retval = index;
		goto err_file;
		goto err_file;
	}
	}


	mutex_unlock(&devpts_mutex);

	mutex_lock(&tty_mutex);
	mutex_lock(&tty_mutex);
	mutex_lock(&devpts_mutex);
	mutex_lock(&devpts_mutex);
	tty = tty_init_dev(ptm_driver, index);
	tty = tty_init_dev(ptm_driver, index);
	mutex_unlock(&devpts_mutex);
	tty_lock();
	mutex_unlock(&tty_mutex);


	if (IS_ERR(tty)) {
	if (IS_ERR(tty)) {
		retval = PTR_ERR(tty);
		retval = PTR_ERR(tty);
		goto out;
		goto out;
	}
	}


	/* The tty returned here is locked so we can safely
	   drop the mutex */
	mutex_unlock(&devpts_mutex);
	mutex_unlock(&tty_mutex);

	set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
	set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */


	tty_add_file(tty, filp);
	tty_add_file(tty, filp);
@@ -654,16 +656,17 @@ static int ptmx_open(struct inode *inode, struct file *filp)
	if (retval)
	if (retval)
		goto err_release;
		goto err_release;


	tty_unlock();
	tty_unlock(tty);
	return 0;
	return 0;
err_release:
err_release:
	tty_unlock();
	tty_unlock(tty);
	tty_release(inode, filp);
	tty_release(inode, filp);
	return retval;
	return retval;
out:
out:
	mutex_unlock(&tty_mutex);
	devpts_kill_index(inode, index);
	devpts_kill_index(inode, index);
	tty_unlock();
err_file:
err_file:
        mutex_unlock(&devpts_mutex);
	tty_free_file(filp);
	tty_free_file(filp);
	return retval;
	return retval;
}
}
Loading