All of lore.kernel.org
 help / color / mirror / Atom feed
From: cael <juanfengpy@gmail.com>
To: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jirislaby@kernel.org>,
	linux-serial <linux-serial@vger.kernel.org>
Subject: Re: tty: fix a possible hang on tty device
Date: Mon, 30 May 2022 21:13:26 +0800	[thread overview]
Message-ID: <CAPmgiUK=aTDJjPYooQGDbNvdOs+z6AbAj5zU7e_0SJhSk2pz9w@mail.gmail.com> (raw)
In-Reply-To: <269a9a97-dc62-a89-d978-3be8e9d1f7e4@linux.intel.com>

Thanks, You are right, barrier is needed here. I changed the patch as follows:
1) WRITE_ONCE and READ_ONCE is used to access ldata->no_room since
n_tty_kick_worker  would be called in kworker and reader cpu;
2) smp_mb added in chars_in_buffer as this function will be called in
reader and kworker, accessing commit_head and read_tail; and to make
sure that read_tail is not read before setting no_room in
n_tty_receive_buf_common;
3) smp_mb added in n_tty_read to make sure that no_room is not read
before setting read_tail.
---
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index efc72104c840..3327687da0d3 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -201,8 +201,8 @@ static void n_tty_kick_worker(struct tty_struct *tty)
        struct n_tty_data *ldata = tty->disc_data;

        /* Did the input worker stop? Restart it */
-       if (unlikely(ldata->no_room)) {
-               ldata->no_room = 0;
+       if (unlikely(READ_ONCE(ldata->no_room))) {
+               WRITE_ONCE(ldata->no_room, 0);

                WARN_RATELIMIT(tty->port->itty == NULL,
                                "scheduling with invalid itty\n");
@@ -221,6 +221,7 @@ static ssize_t chars_in_buffer(struct tty_struct *tty)
        struct n_tty_data *ldata = tty->disc_data;
        ssize_t n = 0;

+       smp_mb();
        if (!ldata->icanon)
                n = ldata->commit_head - ldata->read_tail;
        else
@@ -1632,7 +1633,7 @@ n_tty_receive_buf_common(struct tty_struct *tty,
const unsigned char *cp,
                        if (overflow && room < 0)
                                ldata->read_head--;
                        room = overflow;
-                       ldata->no_room = flow && !room;
+                       WRITE_ONCE(ldata->no_room, flow && !room);
                } else
                        overflow = 0;

@@ -1663,6 +1664,9 @@ n_tty_receive_buf_common(struct tty_struct *tty,
const unsigned char *cp,
        } else
                n_tty_check_throttle(tty);

+       if (!chars_in_buffer(tty))
+               n_tty_kick_worker(tty);
+
        up_read(&tty->termios_rwsem);

        return rcvd;
@@ -2180,8 +2184,10 @@ static ssize_t n_tty_read(struct tty_struct
*tty, struct file *file,
                if (time)
                        timeout = time;
        }
-       if (tail != ldata->read_tail)
+       if (tail != ldata->read_tail) {
+               smp_mb();
                n_tty_kick_worker(tty);
+       }
        up_read(&tty->termios_rwsem);

        remove_wait_queue(&tty->read_wait, &wait);
--
2.27.0

Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> 于2022年5月25日周三 19:21写道:
>
> On Wed, 25 May 2022, cael wrote:
>
> > >Now you switched to an entirely different case, not the one we were
> > >talking about. ...There is no ldisc->no_room = true race in the case
> > >you now described.
> > So, I think we should back to the case ldata->no_room=true as
> > ldata->no_room=false seems harmless.
> >
> > >I'm not worried about the case where both cpus call n_tty_kick_worker but
> > >the case where producer cpu sees chars_in_buffer() > 0 and consumer cpu
> > >!no_room.
> >
> > As ldata->no_room=true is set before checking chars_in_buffer()
>
> Please take a brief look at Documentation/memory-barriers.txt and then
> tell me if you still find this claim to be true.
>
> > if producer
> > finds chars_in_buffer() > 0, then if reader is currently in n_tty_read,
>
> ...Then please do a similar analysis for ldata->read_tail. What guarantees
> its update is seen by the producer cpu when the reader is already past the
> point you think it still must be in?
>
> > when reader quits n_tty_read, n_tty_kick_worker will be called. If reader
> > has already exited n_tty_read, which means that reader still has data to read,
> > next time reader will call n_tty_kick_worker inside n_tty_read too.
>
> C-level analysis alone is not going to be very useful here given you're
> dealing with a concurrency challenge here.
>
>
> --
>  i.
>
>

  reply	other threads:[~2022-05-30 13:13 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-24  2:21 tty: fix a possible hang on tty device cael
2022-05-24  9:11 ` Ilpo Järvinen
2022-05-24 11:09   ` cael
2022-05-24 11:40     ` Ilpo Järvinen
2022-05-24 12:47       ` cael
2022-05-24 13:25         ` Ilpo Järvinen
2022-05-25 10:36           ` cael
2022-05-25 11:21             ` Ilpo Järvinen
2022-05-30 13:13               ` cael [this message]
2022-05-31 12:37                 ` Ilpo Järvinen
2022-06-01  9:38 ` Greg KH
2022-06-01 13:39   ` cael
2022-06-01 14:47     ` Greg KH
2022-06-01 15:28     ` Ilpo Järvinen
2022-06-06 13:40       ` cael
2022-06-06 14:43         ` Greg KH
2022-06-11  6:50           ` cael
2022-06-11  7:32             ` Greg KH
2022-06-13 12:30               ` [PATCH v3] tty: fix hang on tty device with no_room set juanfengpy
2022-06-13 17:20                 ` Greg KH
2022-06-15  3:45                   ` [PATCH v4] " cael
2022-06-15  5:00                     ` Greg KH
2022-06-15  7:57                       ` Ilpo Järvinen
2022-06-15  9:29                         ` Greg KH
2022-06-15 11:17                           ` [PATCH v5] " cael
2022-06-15 11:29                             ` Ilpo Järvinen
2022-06-15 13:33                               ` caelli
2022-06-27 12:05                             ` Greg KH
2022-06-27 13:53                               ` [PATCH v6] " juanfengpy
2023-03-17  2:37                               ` [PATCH v7] " juanfengpy
2023-03-17  2:41                               ` juanfengpy
2023-03-17  6:32                                 ` Jiri Slaby
2023-03-17  7:25                                   ` [PATCH v8] " juanfengpy
2023-04-06  2:44                                     ` [PATCH v9] " juanfengpy
2023-06-15 10:21                                       ` patch "tty: fix hang on tty device with no_room set" added to tty-testing gregkh
2023-06-16  6:14                                       ` patch "tty: fix hang on tty device with no_room set" added to tty-next gregkh
  -- strict thread matches above, loose matches on Subject: below --
2022-05-07  9:11 tty: fix a possible hang on tty device cael
2022-05-17 10:22 ` Greg KH

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='CAPmgiUK=aTDJjPYooQGDbNvdOs+z6AbAj5zU7e_0SJhSk2pz9w@mail.gmail.com' \
    --to=juanfengpy@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jirislaby@kernel.org \
    --cc=linux-serial@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.