Messages in this thread | | | From | Kosuke Tatsukawa <> | Subject | Re: [PATCH] tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c | Date | Thu, 1 Oct 2015 01:55:18 +0000 |
| |
This is a reproducer for the stall problem in drivers/tty/n_tty.c
To reproduce the problem, save the program below as pty.c, compile it, and run it in parallel.
# cc -o pty pty.c # for i in {1..16}; do ./pty& done; wait
The problem can be reproduced on a multi-socket server with recent CPUs. The program always stalled during the first run when I used a server with the following CPU. Intel(R) Xeon(R) CPU E5-2698 v3 @ 2.30GHz 2-sockets x 16-cores x 2-threads
Best regards. --- Kosuke TATSUKAWA | 3rd IT Platform Department | IT Platform Division, NEC Corporation | tatsu@ab.jp.nec.com
--------------------------------< pty.c >-------------------------------- #define _XOPEN_SOURCE #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <sys/wait.h> #include <sys/time.h>
#define COUNT 300000 #define SIZE 1
char data[SIZE];
int main( int argc, char **argv) { int i, fdp, fdt, status; char *slavename; struct termios t; pid_t pid; struct timeval tv1, tv2;
if ((fdp = open("/dev/ptmx", 2)) < 0) { perror("ptmx open"); exit(1); } grantpt(fdp); unlockpt(fdp); slavename = ptsname(fdp); if ((fdt = open(slavename, 2)) < 0) { perror("pty open"); close(fdp); exit(1); } tcgetattr(fdt, &t); t.c_lflag &= ~ECHO; t.c_oflag &= ~OPOST; t.c_lflag &= ~ICANON; t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(fdt, TCSANOW, &t);
tcgetattr(fdp, &t); t.c_lflag &= ~ECHO; t.c_oflag &= ~OPOST; t.c_lflag &= ~ICANON; t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(fdp, TCSANOW, &t);
memset(data, 'A', SIZE);
if ((pid = fork()) < 0) { perror("fork"); close(fdt); close(fdp); exit(1); } if (pid == 0) { /* Child */ sleep(1); for (i = 0; i < COUNT; i++) { if (write(fdt, data, SIZE) != SIZE) { perror("write fdt"); exit(1); } if (read(fdt, data, SIZE) != SIZE) { perror("read fdt"); exit(1); } } exit(0); } else { /* Parent */ for (i = 0; i < COUNT; i++) { if (i == 1) gettimeofday(&tv1, NULL); if (read(fdp, data, SIZE) != SIZE) { perror("read fdp"); exit(1); } if (write(fdp, data, SIZE) != SIZE) { perror("write fdp"); exit(1); } } } gettimeofday(&tv2, NULL); #if 0 printf("%d\n", (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec); #endif wait(&status); exit(0); }
| |