Tại sao trình điều khiển 8250 UART không đánh thức TTY nếu hơn 256 ký tự đang chờ xử lý?


8

Động lực của điều kiện if-in này là void serial8250_tx_chars(struct uart_8250_port *up)gì?

if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
    uart_write_wakeup(port);

Nó đã ở đó kể từ Linux 1.1.13 (tháng 5 năm 1994) và lặp lại trong hầu hết các trình điều khiển UART.

Bối cảnh: Linux 3.4.91 tùy chỉnh, hệ thống nhúng trên ARMv7, cổng UART 0 được cấu hình cho 38400 baud, 16 byte FIFO cho i / o. Không ai có thể thay đổi điều này trong thiết lập của chúng tôi.

Khi printf-ing rất nhiều vào giao diện điều khiển thông qua UART, các 4KB-đệm bên trong ( UART_XMIT_SIZE) đầy lên và sau đó quầy hàng quá trình sử dụng không gian cho đến khi đệm được làm trống (mất một giây tại 38400 baud!). Sau đó, hành vi này lặp lại. Điều này là do chức năng n_tty_write()chuyển sang chế độ ngủ khi bộ đệm đầy và không được đánh thức trong một thời gian dài vì tình trạng nghi vấn ở trên.

Tôi sẽ thấy nó tự nhiên và hiệu quả hơn nếu kiểm tra này được gỡ bỏ đơn giản. Sau đó, các bản in sẽ lấp đầy bộ đệm nhanh nhất có thể, và sau đó tiếp tục với tốc độ mà bộ đệm đang được làm trống , thay vì xử lý cụm mà tôi đang quan sát.

Nó hoạt động tốt trong môi trường của tôi nhưng chắc chắn tôi đang thiếu hoặc hiểu sai điều gì đó. Phải có một lý do cho việc thực hiện hiện tại. Có bất kỳ tác dụng phụ nếu tôi loại bỏ tình trạng đó?

Như một câu hỏi phụ: có các tùy chọn cấu hình để điều chỉnh hành vi này, ví dụ: để printf luôn trả về ngay lập tức và loại bỏ đầu ra nếu bộ đệm đầy?


Không biết quá nhiều về điều này, linh cảm của tôi là thế này: Đây là một thiết lập bàn điều khiển nối tiếp Linux thông thường. Tôi đã làm việc với những người trên phần cứng x86 tiêu chuẩn. Đối với các kết nối nối tiếp trực tiếp, tôi luôn phải sử dụng điều khiển luồng phần cứng. Có thể là một ý tưởng.
vasquez

1
Có khả năng là một sự khác biệt hiệu quả. Tại sao không chỉ đặt WAKEUP_CHARS thành một cái gì đó như UART_XMIT_SIZE - 128?
James Youngman

@JamesYoungman Trên thực tế, đó là những gì tôi đã làm. Chúc mừng!
Hans W. Heckel

Câu trả lời:


2

Đó là một biện pháp hiệu quả. CPU chạy nhanh hơn cổng nối tiếp đến mức nếu hạt nhân cho phép quá trình không gian người dùng chạy mỗi khi có một chút chỗ trống trong bộ đệm, thì cuối cùng sẽ thực hiện một chuyến đi đến không gian người dùng và quay lại cho mỗi byte dữ liệu. Điều đó rất lãng phí thời gian của CPU:

$ time dd if=/dev/zero of=/dev/null bs=1 count=10000000
10000000+0 records in
10000000+0 records out
10000000 bytes (10 MB, 9.5 MiB) copied, 5.95145 s, 1.7 MB/s

real    0m5.954s
user    0m1.960s
sys     0m3.992s

$ time dd if=/dev/zero of=/dev/null bs=1000 count=10000
10000+0 records in
10000+0 records out
10000000 bytes (10 MB, 9.5 MiB) copied, 0.011041 s, 906 MB/s

real    0m0.014s
user    0m0.000s
sys     0m0.012s

Thử nghiệm trên thậm chí không đọc và viết một thiết bị thực: sự khác biệt toàn bộ thời gian là tần suất hệ thống nảy giữa không gian người dùng và không gian nhân.

Nếu không gian người dùng không muốn được giữ, nó có thể sử dụng I / O không chặn hoặc nó có thể kiểm tra sử dụng select()cuộc gọi để xem có chỗ nào để ghi vào thiết bị không ... và nếu không, nó có thể kết xuất Phần còn lại vào một bộ đệm của riêng nó và tiếp tục xử lý. Phải thừa nhận rằng điều đó làm phức tạp mọi thứ, vì bây giờ bạn có một bộ đệm mà bạn phải xóa ... nhưng nếu bạn đang sử dụng stdio, điều đó thường đúng.


Điều này hỗ trợ nhận xét của @James về hiệu quả ở trên. Bây giờ nó có ý nghĩa hơn nhiều đối với tôi. Cảm ơn, cũng cho những con số!
Hans W. Heckel

Cần lưu ý rằng kể từ kernel 2.6, câu hỏi này tham chiếu mã thường xuất hiện trong trình điều khiển lớp thấp hơn (ví dụ: trình điều khiển UART). Các trình điều khiển này cung cấp lớp cao hơn, serial_core, phương tiện để tương tác với phần cứng. Đó là lõi nối tiếp thực sự tương tác với không gian người dùng (trừ khi trình điều khiển phần cứng thực hiện ioctls của chính nó hoặc một cái gì đó tương tự). Tôi tin rằng người trả lời vẫn trả lời.
Andrew Falanga
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.