Skip to contentSkip to conversation

tty_reopen() returning -EIO because port is closing

DISCUSSION Grant Edwards 2 participants 4 messages Jan 18, 2013 – Jan 20, 2013 TTY layer and serial drivers

lore
Share & tools
lore
#0 lore raw

During testing of a tty driver that's just been updated to use the tty_port_ helper functions, I'm seeing a test failure in user-space when open() returns -EIO.

The failure occurs sporadically (maybe 1 failure per 100 opens) when running a test that has multiple threads all opening and closing the same serial port (more or less at random).

It's worth noting that my port activate and shutdown functions sleep.

Typically, they sleep for a few ms [this is the case during the tests I've been running]. But, there are use cases where they could sleep for hundreds of ms.

I've tracked the failure to tty_reopen() in tty_io.c [3.8-rc3]:

  1331	static int tty_reopen(struct tty_struct *tty)
  1332	{
  1333	        struct tty_driver *driver = tty->driver;
  1334	
  1335	        if (test_bit(TTY_CLOSING, &tty->flags) ||
  1336	                        test_bit(TTY_HUPPING, &tty->flags) ||
  1337	                        test_bit(TTY_LDISC_CHANGING, &tty->flags))
  1338	                return -EIO;

Line 1338 is returning -EIO because test_bit(TTY_CLOSING, &tty->flags) is true.

Can this be caused by a bug in my driver?

If not, is it a bug in the tty layer?

Does Posix say than an open() may fail if it's called while another process is calling close()? IOW, is user-space code expected to retry an open() call that returns EIO? [I've never seen user-space code that did that...]

Signature · 3 lines
Grant Edwards               grant.b.edwards        Yow! I'm having a RELIGIOUS
                                  at               EXPERIENCE ... and I don't
                              gmail.com            take any DRUGS
#1 lore raw
Quoted 1 line

If not, is it a bug in the tty layer?

Our tty layer has always done this.

Quoted 4 lines

Does Posix say than an open() may fail if it's called while another process is calling close()? IOW, is user-space code expected to retry an open() call that returns EIO? [I've never seen user-space code that did that...]

Interesting question. I've never liked the fact we do it (its rude to the userspace) but it's not clear what the correct semantics are of an open as a port closes, given the close must complete first including any drains and control changes and the open may well not expect to block or hang for a long time.

Alan

#2 lore raw
Quoted 4 lines · Alan Cox
Quoted 2 lines

If not, is it a bug in the tty layer?

Our tty layer has always done this.

We'll call it a feature, then.

I don't remember ever seeing it before. Either the test is different (which might be), or the old non-helper tty driver would somehow cause the open() to block/retry.

It looks like the old open() code checked to see if the port was closing, waited for the close to finish, and then returned either EAGAIN or ERESTARTSYS:

  // If we are in the process of closing, wait for it to complete, then return
  if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING) 
    {
       wait_event_interruptible(info->close_wait, !(info->flags & ASYNC_CLOSING));
       return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS;
    }

I do think I recall seeing a user-space open() block for some time under certain circumstances.

Quoted 10 lines
Quoted 4 lines

Does Posix say than an open() may fail if it's called while another process is calling close()? IOW, is user-space code expected to retry an open() call that returns EIO? [I've never seen user-space code that did that...]

Interesting question. I've never liked the fact we do it (its rude to the userspace) but it's not clear what the correct semantics are of an open as a port closes, given the close must complete first including any drains and control changes and the open may well not expect to block or hang for a long time.

If my driver now behaves the same as the "standard" driver where it didn't used to, I'm going to claim it's an improvement.

Signature · 4 lines
Grant Edwards               grant.b.edwards        Yow! I'm sitting on my
                                  at               SPEED QUEEN ... To me,
                              gmail.com            it's ENJOYABLE ... I'm WARM
                                                   ... I'm VIBRATORY ...
#3 lore raw
Quoted 2 lines

If my driver now behaves the same as the "standard" driver where it didn't used to, I'm going to claim it's an improvement.

And given any fix for that behaviour in future would be in the generic shared code it also means you'll automatically pick it up. That's one of the big reasons for the tty_port code - to kill the hundreds of replicated differently buggy open implementations we had in drivers

Alan