2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-27 06:34:11 +08:00

tty: cumulate and document tty_struct::ctrl* members

Group the ctrl members under a single struct called ctrl. The new struct
contains 'pgrp', 'session', 'pktstatus', and 'packet'. 'pktstatus' and
'packet' used to be bits in a bitfield. The struct also contains the
lock protecting them to share the same cache line.

Note that commit c545b66c69 (tty: Serialize tcflow() with other tty
flow control changes) added a padding to the original bitfield. It was
for the bitfield to occupy a whole 64b word to avoid interferring stores
on Alpha (cannot we evaporate this arch with weird implications to C
code yet?). But it doesn't work as expected as the padding
(tty_struct::ctrl_unused) is aligned to a 8B boundary too and occupies
some bytes from the next word.

So make it reliable by:
1) setting __aligned of the struct -- that aligns the start, and
2) making 'unsigned long unused[0]' as the last member of the struct --
   pads the end.

Add a kerneldoc comment for this grouped members.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: netdev@vger.kernel.org
Link: https://lore.kernel.org/r/20210505091928.22010-14-jslaby@suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Jiri Slaby 2021-05-05 11:19:06 +02:00 committed by Greg Kroah-Hartman
parent 6e94dbc7a4
commit 64d608db38
7 changed files with 130 additions and 122 deletions

View File

@ -89,7 +89,7 @@ static inline void update_tty_status(struct ser_device *ser)
ser->tty_status =
ser->tty->flow.stopped << 5 |
ser->tty->flow.tco_stopped << 3 |
ser->tty->packet << 2;
ser->tty->ctrl.packet << 2;
}
static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
{

View File

@ -342,10 +342,10 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty)
{
unsigned long flags;
if (tty->link->packet) {
spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->ctrl_status |= TIOCPKT_FLUSHREAD;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->link->ctrl.packet) {
spin_lock_irqsave(&tty->ctrl.lock, flags);
tty->ctrl.pktstatus |= TIOCPKT_FLUSHREAD;
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
wake_up_interruptible(&tty->link->read_wait);
}
}
@ -361,7 +361,7 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty)
* Holds termios_rwsem to exclude producer/consumer while
* buffer indices are reset.
*
* Locking: ctrl_lock, exclusive termios_rwsem
* Locking: ctrl.lock, exclusive termios_rwsem
*/
static void n_tty_flush_buffer(struct tty_struct *tty)
@ -1103,7 +1103,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
* buffer is 'output'. The signal is processed first to alert any current
* readers or writers to discontinue and exit their i/o loops.
*
* Locking: ctrl_lock
* Locking: ctrl.lock
*/
static void __isig(int sig, struct tty_struct *tty)
@ -2025,7 +2025,7 @@ static bool canon_copy_from_read_buf(struct tty_struct *tty,
*
* Locking: redirected write test is safe
* current->signal->tty check is safe
* ctrl_lock to safely reference tty->pgrp
* ctrl.lock to safely reference tty->ctrl.pgrp
*/
static int job_control(struct tty_struct *tty, struct file *file)
@ -2072,7 +2072,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
int minimum, time;
ssize_t retval = 0;
long timeout;
int packet;
bool packet;
size_t tail;
/*
@ -2128,20 +2128,20 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
}
}
packet = tty->packet;
packet = tty->ctrl.packet;
tail = ldata->read_tail;
add_wait_queue(&tty->read_wait, &wait);
while (nr) {
/* First test for status change. */
if (packet && tty->link->ctrl_status) {
if (packet && tty->link->ctrl.pktstatus) {
unsigned char cs;
if (kb != kbuf)
break;
spin_lock_irq(&tty->link->ctrl_lock);
cs = tty->link->ctrl_status;
tty->link->ctrl_status = 0;
spin_unlock_irq(&tty->link->ctrl_lock);
spin_lock_irq(&tty->link->ctrl.lock);
cs = tty->link->ctrl.pktstatus;
tty->link->ctrl.pktstatus = 0;
spin_unlock_irq(&tty->link->ctrl.lock);
*kb++ = cs;
nr--;
break;
@ -2368,7 +2368,7 @@ static __poll_t n_tty_poll(struct tty_struct *tty, struct file *file,
if (input_available_p(tty, 1))
mask |= EPOLLIN | EPOLLRDNORM;
}
if (tty->packet && tty->link->ctrl_status)
if (tty->ctrl.packet && tty->link->ctrl.pktstatus)
mask |= EPOLLPRI | EPOLLIN | EPOLLRDNORM;
if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
mask |= EPOLLHUP;

View File

@ -57,9 +57,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
set_bit(TTY_IO_ERROR, &tty->flags);
wake_up_interruptible(&tty->read_wait);
wake_up_interruptible(&tty->write_wait);
spin_lock_irq(&tty->ctrl_lock);
tty->packet = 0;
spin_unlock_irq(&tty->ctrl_lock);
spin_lock_irq(&tty->ctrl.lock);
tty->ctrl.packet = false;
spin_unlock_irq(&tty->ctrl.lock);
/* Review - krefs on tty_link ?? */
if (!tty->link)
return;
@ -185,16 +185,16 @@ static int pty_set_pktmode(struct tty_struct *tty, int __user *arg)
if (get_user(pktmode, arg))
return -EFAULT;
spin_lock_irq(&tty->ctrl_lock);
spin_lock_irq(&tty->ctrl.lock);
if (pktmode) {
if (!tty->packet) {
tty->link->ctrl_status = 0;
if (!tty->ctrl.packet) {
tty->link->ctrl.pktstatus = 0;
smp_mb();
tty->packet = 1;
tty->ctrl.packet = true;
}
} else
tty->packet = 0;
spin_unlock_irq(&tty->ctrl_lock);
tty->ctrl.packet = false;
spin_unlock_irq(&tty->ctrl.lock);
return 0;
}
@ -202,7 +202,7 @@ static int pty_set_pktmode(struct tty_struct *tty, int __user *arg)
/* Get the packet mode of a pty */
static int pty_get_pktmode(struct tty_struct *tty, int __user *arg)
{
int pktmode = tty->packet;
int pktmode = tty->ctrl.packet;
return put_user(pktmode, arg);
}
@ -232,11 +232,11 @@ static void pty_flush_buffer(struct tty_struct *tty)
return;
tty_buffer_flush(to, NULL);
if (to->packet) {
spin_lock_irq(&tty->ctrl_lock);
tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
if (to->ctrl.packet) {
spin_lock_irq(&tty->ctrl.lock);
tty->ctrl.pktstatus |= TIOCPKT_FLUSHWRITE;
wake_up_interruptible(&to->read_wait);
spin_unlock_irq(&tty->ctrl_lock);
spin_unlock_irq(&tty->ctrl.lock);
}
}
@ -266,7 +266,7 @@ static void pty_set_termios(struct tty_struct *tty,
struct ktermios *old_termios)
{
/* See if packet mode change of state. */
if (tty->link && tty->link->packet) {
if (tty->link && tty->link->ctrl.packet) {
int extproc = (old_termios->c_lflag & EXTPROC) | L_EXTPROC(tty);
int old_flow = ((old_termios->c_iflag & IXON) &&
(old_termios->c_cc[VSTOP] == '\023') &&
@ -275,17 +275,17 @@ static void pty_set_termios(struct tty_struct *tty,
STOP_CHAR(tty) == '\023' &&
START_CHAR(tty) == '\021');
if ((old_flow != new_flow) || extproc) {
spin_lock_irq(&tty->ctrl_lock);
spin_lock_irq(&tty->ctrl.lock);
if (old_flow != new_flow) {
tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
tty->ctrl.pktstatus &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
if (new_flow)
tty->ctrl_status |= TIOCPKT_DOSTOP;
tty->ctrl.pktstatus |= TIOCPKT_DOSTOP;
else
tty->ctrl_status |= TIOCPKT_NOSTOP;
tty->ctrl.pktstatus |= TIOCPKT_NOSTOP;
}
if (extproc)
tty->ctrl_status |= TIOCPKT_IOCTL;
spin_unlock_irq(&tty->ctrl_lock);
tty->ctrl.pktstatus |= TIOCPKT_IOCTL;
spin_unlock_irq(&tty->ctrl.lock);
wake_up_interruptible(&tty->link->read_wait);
}
}
@ -346,11 +346,11 @@ static void pty_start(struct tty_struct *tty)
{
unsigned long flags;
if (tty->link && tty->link->packet) {
spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->ctrl_status &= ~TIOCPKT_STOP;
tty->ctrl_status |= TIOCPKT_START;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->link && tty->link->ctrl.packet) {
spin_lock_irqsave(&tty->ctrl.lock, flags);
tty->ctrl.pktstatus &= ~TIOCPKT_STOP;
tty->ctrl.pktstatus |= TIOCPKT_START;
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
wake_up_interruptible_poll(&tty->link->read_wait, EPOLLIN);
}
}
@ -359,11 +359,11 @@ static void pty_stop(struct tty_struct *tty)
{
unsigned long flags;
if (tty->link && tty->link->packet) {
spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->ctrl_status &= ~TIOCPKT_START;
tty->ctrl_status |= TIOCPKT_STOP;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->link && tty->link->ctrl.packet) {
spin_lock_irqsave(&tty->ctrl.lock, flags);
tty->ctrl.pktstatus &= ~TIOCPKT_START;
tty->ctrl.pktstatus |= TIOCPKT_STOP;
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
wake_up_interruptible_poll(&tty->link->read_wait, EPOLLIN);
}
}

View File

@ -638,15 +638,15 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
tty_ldisc_hangup(tty, cons_filp != NULL);
spin_lock_irq(&tty->ctrl_lock);
spin_lock_irq(&tty->ctrl.lock);
clear_bit(TTY_THROTTLED, &tty->flags);
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
put_pid(tty->session);
put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
tty->ctrl_status = 0;
spin_unlock_irq(&tty->ctrl_lock);
put_pid(tty->ctrl.session);
put_pid(tty->ctrl.pgrp);
tty->ctrl.session = NULL;
tty->ctrl.pgrp = NULL;
tty->ctrl.pktstatus = 0;
spin_unlock_irq(&tty->ctrl.lock);
/*
* If one of the devices matches a console pointer, we
@ -1559,8 +1559,8 @@ static void release_one_tty(struct work_struct *work)
list_del_init(&tty->tty_files);
spin_unlock(&tty->files_lock);
put_pid(tty->pgrp);
put_pid(tty->session);
put_pid(tty->ctrl.pgrp);
put_pid(tty->ctrl.session);
free_tty_struct(tty);
}
@ -1861,9 +1861,9 @@ int tty_release(struct inode *inode, struct file *filp)
*/
if (!tty->count) {
read_lock(&tasklist_lock);
session_clear_tty(tty->session);
session_clear_tty(tty->ctrl.session);
if (o_tty)
session_clear_tty(o_tty->session);
session_clear_tty(o_tty->ctrl.session);
read_unlock(&tasklist_lock);
}
@ -2250,16 +2250,16 @@ static int __tty_fasync(int fd, struct file *filp, int on)
enum pid_type type;
struct pid *pid;
spin_lock_irqsave(&tty->ctrl_lock, flags);
if (tty->pgrp) {
pid = tty->pgrp;
spin_lock_irqsave(&tty->ctrl.lock, flags);
if (tty->ctrl.pgrp) {
pid = tty->ctrl.pgrp;
type = PIDTYPE_PGID;
} else {
pid = task_pid(current);
type = PIDTYPE_TGID;
}
get_pid(pid);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
__f_setown(filp, pid, type, 0);
put_pid(pid);
retval = 0;
@ -2381,7 +2381,7 @@ EXPORT_SYMBOL(tty_do_resize);
*
* Locking:
* Driver dependent. The default do_resize method takes the
* tty termios mutex and ctrl_lock. The console takes its own lock
* tty termios mutex and ctrl.lock. The console takes its own lock
* then calls into the default method.
*/
@ -3039,9 +3039,9 @@ void __do_SAK(struct tty_struct *tty)
if (!tty)
return;
spin_lock_irqsave(&tty->ctrl_lock, flags);
session = get_pid(tty->session);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
spin_lock_irqsave(&tty->ctrl.lock, flags);
session = get_pid(tty->ctrl.session);
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
tty_ldisc_flush(tty);
@ -3129,8 +3129,8 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
kfree(tty);
return NULL;
}
tty->session = NULL;
tty->pgrp = NULL;
tty->ctrl.session = NULL;
tty->ctrl.pgrp = NULL;
mutex_init(&tty->legacy_mutex);
mutex_init(&tty->throttle_mutex);
init_rwsem(&tty->termios_rwsem);
@ -3140,7 +3140,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
init_waitqueue_head(&tty->read_wait);
INIT_WORK(&tty->hangup_work, do_tty_hangup);
mutex_init(&tty->atomic_write_lock);
spin_lock_init(&tty->ctrl_lock);
spin_lock_init(&tty->ctrl.lock);
spin_lock_init(&tty->flow.lock);
spin_lock_init(&tty->files_lock);
INIT_LIST_HEAD(&tty->tty_files);

View File

@ -28,7 +28,7 @@ static int is_ignored(int sig)
* not in the foreground, send a SIGTTOU. If the signal is blocked or
* ignored, go ahead and perform the operation. (POSIX 7.2)
*
* Locking: ctrl_lock
* Locking: ctrl.lock
*/
int __tty_check_change(struct tty_struct *tty, int sig)
{
@ -42,9 +42,9 @@ int __tty_check_change(struct tty_struct *tty, int sig)
rcu_read_lock();
pgrp = task_pgrp(current);
spin_lock_irqsave(&tty->ctrl_lock, flags);
tty_pgrp = tty->pgrp;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
spin_lock_irqsave(&tty->ctrl.lock, flags);
tty_pgrp = tty->ctrl.pgrp;
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
if (tty_pgrp && pgrp != tty_pgrp) {
if (is_ignored(sig)) {
@ -99,16 +99,16 @@ static void __proc_set_tty(struct tty_struct *tty)
{
unsigned long flags;
spin_lock_irqsave(&tty->ctrl_lock, flags);
spin_lock_irqsave(&tty->ctrl.lock, flags);
/*
* The session and fg pgrp references will be non-NULL if
* tiocsctty() is stealing the controlling tty
*/
put_pid(tty->session);
put_pid(tty->pgrp);
tty->pgrp = get_pid(task_pgrp(current));
tty->session = get_pid(task_session(current));
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
put_pid(tty->ctrl.session);
put_pid(tty->ctrl.pgrp);
tty->ctrl.pgrp = get_pid(task_pgrp(current));
tty->ctrl.session = get_pid(task_session(current));
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
if (current->signal->tty) {
tty_debug(tty, "current tty %s not NULL!!\n",
current->signal->tty->name);
@ -135,7 +135,7 @@ void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty)
spin_lock_irq(&current->sighand->siglock);
if (current->signal->leader &&
!current->signal->tty &&
tty->session == NULL) {
tty->ctrl.session == NULL) {
/*
* Don't let a process that only has write access to the tty
* obtain the privileges associated with having a tty as
@ -200,8 +200,8 @@ int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
struct pid *tty_pgrp = NULL;
read_lock(&tasklist_lock);
if (tty->session) {
do_each_pid_task(tty->session, PIDTYPE_SID, p) {
if (tty->ctrl.session) {
do_each_pid_task(tty->ctrl.session, PIDTYPE_SID, p) {
spin_lock_irq(&p->sighand->siglock);
if (p->signal->tty == tty) {
p->signal->tty = NULL;
@ -218,13 +218,14 @@ int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
__group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
put_pid(p->signal->tty_old_pgrp); /* A noop */
spin_lock(&tty->ctrl_lock);
tty_pgrp = get_pid(tty->pgrp);
if (tty->pgrp)
p->signal->tty_old_pgrp = get_pid(tty->pgrp);
spin_unlock(&tty->ctrl_lock);
spin_lock(&tty->ctrl.lock);
tty_pgrp = get_pid(tty->ctrl.pgrp);
if (tty->ctrl.pgrp)
p->signal->tty_old_pgrp =
get_pid(tty->ctrl.pgrp);
spin_unlock(&tty->ctrl.lock);
spin_unlock_irq(&p->sighand->siglock);
} while_each_pid_task(tty->session, PIDTYPE_SID, p);
} while_each_pid_task(tty->ctrl.session, PIDTYPE_SID, p);
}
read_unlock(&tasklist_lock);
@ -309,12 +310,12 @@ void disassociate_ctty(int on_exit)
unsigned long flags;
tty_lock(tty);
spin_lock_irqsave(&tty->ctrl_lock, flags);
put_pid(tty->session);
put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
spin_lock_irqsave(&tty->ctrl.lock, flags);
put_pid(tty->ctrl.session);
put_pid(tty->ctrl.pgrp);
tty->ctrl.session = NULL;
tty->ctrl.pgrp = NULL;
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
tty_unlock(tty);
tty_kref_put(tty);
}
@ -363,7 +364,8 @@ static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
tty_lock(tty);
read_lock(&tasklist_lock);
if (current->signal->leader && (task_session(current) == tty->session))
if (current->signal->leader &&
task_session(current) == tty->ctrl.session)
goto unlock;
/*
@ -375,7 +377,7 @@ static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
goto unlock;
}
if (tty->session) {
if (tty->ctrl.session) {
/*
* This tty is already the controlling
* tty for another session group!
@ -384,7 +386,7 @@ static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
/*
* Steal it away
*/
session_clear_tty(tty->session);
session_clear_tty(tty->ctrl.session);
} else {
ret = -EPERM;
goto unlock;
@ -416,9 +418,9 @@ struct pid *tty_get_pgrp(struct tty_struct *tty)
unsigned long flags;
struct pid *pgrp;
spin_lock_irqsave(&tty->ctrl_lock, flags);
pgrp = get_pid(tty->pgrp);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
spin_lock_irqsave(&tty->ctrl.lock, flags);
pgrp = get_pid(tty->ctrl.pgrp);
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
return pgrp;
}
@ -499,10 +501,10 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
if (pgrp_nr < 0)
return -EINVAL;
spin_lock_irq(&real_tty->ctrl_lock);
spin_lock_irq(&real_tty->ctrl.lock);
if (!current->signal->tty ||
(current->signal->tty != real_tty) ||
(real_tty->session != task_session(current))) {
(real_tty->ctrl.session != task_session(current))) {
retval = -ENOTTY;
goto out_unlock_ctrl;
}
@ -515,12 +517,12 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock;
retval = 0;
put_pid(real_tty->pgrp);
real_tty->pgrp = get_pid(pgrp);
put_pid(real_tty->ctrl.pgrp);
real_tty->ctrl.pgrp = get_pid(pgrp);
out_unlock:
rcu_read_unlock();
out_unlock_ctrl:
spin_unlock_irq(&real_tty->ctrl_lock);
spin_unlock_irq(&real_tty->ctrl.lock);
return retval;
}
@ -545,16 +547,16 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
spin_lock_irqsave(&real_tty->ctrl_lock, flags);
if (!real_tty->session)
spin_lock_irqsave(&real_tty->ctrl.lock, flags);
if (!real_tty->ctrl.session)
goto err;
sid = pid_vnr(real_tty->session);
spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
sid = pid_vnr(real_tty->ctrl.session);
spin_unlock_irqrestore(&real_tty->ctrl.lock, flags);
return put_user(sid, p);
err:
spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
spin_unlock_irqrestore(&real_tty->ctrl.lock, flags);
return -ENOTTY;
}

View File

@ -1189,7 +1189,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,
* information and perform any necessary signal handling.
*
* Caller must hold the console semaphore. Takes the termios rwsem and
* ctrl_lock of the tty IFF a tty is passed.
* ctrl.lock of the tty IFF a tty is passed.
*/
static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
@ -1355,7 +1355,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
* the actual work.
*
* Takes the console sem and the called methods then take the tty
* termios_rwsem and the tty ctrl_lock in that order.
* termios_rwsem and the tty ctrl.lock in that order.
*/
static int vt_resize(struct tty_struct *tty, struct winsize *ws)
{

View File

@ -255,6 +255,13 @@ struct tty_operations;
* @flow.unused: alignment for Alpha, so that no members other than @flow.* are
* modified by the same 64b word store. The @flow's __aligned is
* there for the very same reason.
* @ctrl.lock: lock for ctrl members
* @ctrl.pgrp: process group of this tty (setpgrp(2))
* @ctrl.session: session of this tty (setsid(2)). Writes are protected by both
* @ctrl.lock and legacy mutex, readers must use at least one of
* them.
* @ctrl.pktstatus: packet mode status (bitwise OR of TIOCPKT_* constants)
* @ctrl.packet: packet mode enabled
*
* All of the state associated with a tty while the tty is open. Persistent
* storage for tty devices is referenced here as @port in struct tty_port.
@ -276,16 +283,9 @@ struct tty_struct {
struct mutex throttle_mutex;
struct rw_semaphore termios_rwsem;
struct mutex winsize_mutex;
spinlock_t ctrl_lock;
/* Termios values are protected by the termios rwsem */
struct ktermios termios, termios_locked;
char name[64];
struct pid *pgrp; /* Protected by ctrl lock */
/*
* Writes protected by both ctrl lock and legacy mutex, readers must use
* at least one of them.
*/
struct pid *session;
unsigned long flags;
int count;
struct winsize winsize; /* winsize_mutex */
@ -297,10 +297,16 @@ struct tty_struct {
unsigned long unused[0];
} __aligned(sizeof(unsigned long)) flow;
struct {
spinlock_t lock;
struct pid *pgrp;
struct pid *session;
unsigned char pktstatus;
bool packet;
unsigned long unused[0];
} __aligned(sizeof(unsigned long)) ctrl;
int hw_stopped;
unsigned long ctrl_status:8, /* ctrl_lock */
packet:1,
unused_ctrl:BITS_PER_LONG - 9;
unsigned int receive_room; /* Bytes free for queue */
int flow_change;