From: Jiri Slaby <jslaby@suse.cz>
To: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>,
Paul Fulghum <paulkf@microgate.com>
Cc: Arnd Bergmann <arnd@arndb.de>,
gregkh@linuxfoundation.org, Alan Cox <alan@lxorguk.ukuu.org.uk>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] tty/n_hdlc: fix sleep in !TASK_RUNNING state warning
Date: Thu, 3 Jan 2019 10:09:55 +0100 [thread overview]
Message-ID: <ba6de468-d36d-cd33-9a13-520102b676c6@suse.cz> (raw)
In-Reply-To: <cf9b7323-da1c-20cd-4d50-1080fbe52467@i-love.sakura.ne.jp>
On 02. 01. 19, 16:04, Tetsuo Handa wrote:
> + if (wait_event_interruptible(tty->read_wait,
> + (ret = -EIO, test_bit(TTY_OTHER_CLOSED, &tty->flags)) ||
> + (ret = 0, tty_hung_up_p(file)) ||
> + (rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list)) != NULL ||
> + (ret = -EAGAIN, tty_io_nonblock(tty, file))))
> + return -EINTR;
Oh, that looks really ugly. Could you move all this to a function
returning a bool and taking &ret and &rbuf as parameters?
> + if (rbuf) {
> + if (rbuf->count > nr)
> + /* too large for caller's buffer */
> + ret = -EOVERFLOW;
> + else if (copy_to_user(buf, rbuf->buf, rbuf->count))
> + ret = -EFAULT;
> + else
> + ret = rbuf->count;
> + if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
> + kfree(rbuf);
> + else
> + n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf);
> }
> -
> - remove_wait_queue(&tty->read_wait, &wait);
> - __set_current_state(TASK_RUNNING);
> -
> return ret;
> -
> } /* end of n_hdlc_tty_read() */
>
> /**
> @@ -645,21 +612,13 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
> static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
> const unsigned char *data, size_t count)
> {
> - struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
> + struct n_hdlc *n_hdlc;
> int error = 0;
> - DECLARE_WAITQUEUE(wait, current);
> - struct n_hdlc_buf *tbuf;
> + struct n_hdlc_buf *tbuf = NULL;
>
> if (debuglevel >= DEBUG_LEVEL_INFO)
> printk("%s(%d)n_hdlc_tty_write() called count=%zd\n",
> __FILE__,__LINE__,count);
> -
> - /* Verify pointers */
> - if (!n_hdlc)
> - return -EIO;
> -
> - if (n_hdlc->magic != HDLC_MAGIC)
> - return -EIO;
>
> /* verify frame size */
> if (count > maxframe ) {
> @@ -670,40 +629,14 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
> maxframe );
> count = maxframe;
> }
> -
> - add_wait_queue(&tty->write_wait, &wait);
>
> - for (;;) {
> - set_current_state(TASK_INTERRUPTIBLE);
> -
> - tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
> - if (tbuf)
> - break;
> -
> - if (tty_io_nonblock(tty, file)) {
> - error = -EAGAIN;
> - break;
> - }
> - schedule();
> -
> - n_hdlc = tty2n_hdlc (tty);
> - if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
> - tty != n_hdlc->tty) {
> - printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
> - error = -EIO;
> - break;
> - }
> -
> - if (signal_pending(current)) {
> - error = -EINTR;
> - break;
> - }
> - }
> -
> - __set_current_state(TASK_RUNNING);
> - remove_wait_queue(&tty->write_wait, &wait);
> -
> - if (!error) {
> + if (wait_event_interruptible(tty->write_wait,
> + (error = -EIO, n_hdlc = tty2n_hdlc(tty), /* Verify pointers */
> + !n_hdlc || n_hdlc->magic != HDLC_MAGIC || tty != n_hdlc->tty) ||
> + (tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list)) != NULL ||
> + (error = -EAGAIN, tty_io_nonblock(tty, file))))
> + return -EINTR;
This is even worse. So detto as above?
> + if (tbuf) {
> /* Retrieve the user's buffer */
> memcpy(tbuf->buf, data, count);
>
> @@ -711,8 +644,9 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
> tbuf->count = error = count;
> n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
> n_hdlc_send_frames(n_hdlc,tty);
> + } else if (error == -EIO) {
> + printk("n_hdlc_tty_write: %p invalid!\n", n_hdlc);
> }
> -
> return error;
>
> } /* end of n_hdlc_tty_write() */
>
thanks,
--
js
suse labs
next prev parent reply other threads:[~2019-01-03 9:10 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-29 0:41 WARNING in __might_sleep (2) syzbot
2018-12-29 11:48 ` [PATCH] tty/n_hdlc: fix sleep in !TASK_RUNNING state warning Tetsuo Handa
2019-01-01 3:13 ` Paul Fulghum
2019-01-01 20:28 ` [PATCH] tty/n_hdlc: fix __might_sleep warning Paul Fulghum
2019-01-10 11:38 ` Tetsuo Handa
2019-01-10 12:25 ` Arnd Bergmann
[not found] ` <FEBFE826-8D27-4A0B-86A5-BA559921CADC@microgate.com>
2019-01-02 15:04 ` [PATCH] tty/n_hdlc: fix sleep in !TASK_RUNNING state warning Tetsuo Handa
2019-01-02 20:55 ` Paul Fulghum
2019-01-03 9:09 ` Jiri Slaby [this message]
2019-01-03 11:32 ` Tetsuo Handa
2019-01-03 15:57 ` Paul Fulghum
2019-01-04 10:23 ` Tetsuo Handa
2019-01-04 13:57 ` Paul Fulghum
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=ba6de468-d36d-cd33-9a13-520102b676c6@suse.cz \
--to=jslaby@suse.cz \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=arnd@arndb.de \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=paulkf@microgate.com \
--cc=penguin-kernel@i-love.sakura.ne.jp \
/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®