GNU/Linux >> Belajar Linux >  >> Linux

Linux – Mengapa Masalah “usb-stick Stall” Dilaporkan Pada 2013? Mengapa Masalah Ini Tidak Dipecahkan Dengan Kode “No-i/o Dirty Throttling” yang Ada?

Masalah stik USB yang rusak – LWN.net, November 2013.

Artem S. Tashkinov baru-baru ini mengalami masalah yang akan akrab bagi setidaknya beberapa pembaca LWN. Colokkan perangkat penyimpanan yang lambat (stik USB, katakanlah, atau pemutar media) ke mesin Linux dan tulis banyak data ke dalamnya. Seluruh sistem hanya hang , mungkin selama beberapa menit.

Namun kali ini, Artem membuat pengamatan yang menarik:sistem akan terhenti saat dijalankan dengan kernel 64-bit, tetapi tidak ada masalah yang dialami saat menggunakan kernel 32-bit pada perangkat keras yang sama.

Artikel tersebut menjelaskan bahwa dengan kernel 64-bit, cache halaman kotor (cache writeback) diizinkan untuk tumbuh hingga 20% dari memori secara default. Dengan kernel 32-bit, secara efektif dibatasi hingga ~180MB.

Linus menyarankan untuk membatasinya hingga ~180MB pada 64-bit juga, namun Linux saat ini (v4.18) tidak melakukan ini. Bandingkan patch yang disarankan Linus, dengan fungsi saat ini di Linux 4.18. Argumen terbesar menentang perubahan semacam itu datang dari Dave Chinner. Dia menunjukkan bahwa mengurangi buffering terlalu banyak akan menyebabkan sistem file mengalami fragmentasi. Dia juga menjelaskan bahwa “untuk streaming IO kita biasanya membutuhkan setidaknya
5 detik cache kotor data untuk meratakan penundaan.”

Saya bingung. Mengapa stik USB macet menyebabkan seluruh sistem macet?

Saya bingung karena saya membaca artikel sebelumnya yang menjelaskan tentang penggabungan kode pada tahun 2011 (Linux 3.2). Ini menunjukkan kernel seharusnya mengendalikan cache halaman kotor per perangkat:

Tanpa-I/O pelambatan kotor – LWN.net, 2011

Di situlah set tambalan Fengguang masuk. Dia mencoba membuat loop kontrol yang mampu menentukan berapa banyak halaman yang harus dibiarkan kotor oleh setiap proses pada waktu tertentu. Proses yang melebihi batasnya akan ditidurkan untuk sementara waktu agar sistem writeback dapat mengejarnya.

[…]

Tujuan dari sistem ini adalah untuk menjaga jumlah halaman kotor pada setpoint; jika hal-hal keluar dari jalur, peningkatan jumlah kekuatan akan diterapkan untuk membawa hal-hal kembali ke tempat yang seharusnya.

[…]

Rasio ini tidak dapat benar-benar dihitung, tanpa memperhitungkan perangkat pendukung (BDI). Suatu proses mungkin mengotori halaman yang disimpan pada BDI tertentu, dan sistem mungkin memiliki banyak halaman kotor saat ini, tetapi kebijaksanaan membatasi proses itu juga bergantung pada berapa banyak halaman kotor yang ada untuk BDI tersebut. […] Sebuah BDI dengan sedikit halaman kotor dapat menghapus backlognya dengan cepat, sehingga mungkin mampu untuk memiliki beberapa halaman lagi, bahkan jika sistemnya agak lebih kotor daripada yang mungkin diinginkan. Jadi, set tambalan mengubah pos_ratio yang dihitung untuk BDI tertentu menggunakan rumus rumit yang melihat seberapa jauh BDI spesifik itu dari setpointnya sendiri dan bandwidth yang diamati. Hasil akhirnya adalah pos_ratio yang dimodifikasi yang menjelaskan apakah sistem harus mengotori lebih banyak atau lebih sedikit halaman yang didukung oleh BDI yang diberikan, dan seberapa banyak.

Kontrol per perangkat ditambahkan lebih awal dari ini:Throttling penulisan yang lebih cerdas, 2007 LWN.net. [PATCH 0/23] per perangkat pelambatan kotor -v10. Itu digabungkan di Linux versi 2.6.24.

Jawaban yang Diterima:

  1. Artikel tahun 2013 salah
  2. Kesalahan di LWN? Apakah Anda yakin?
  3. Antrian panjang di perangkat I/O, yang dibuat oleh penulisan balik “latar belakang”
  4. Batasan “no-I/O dirty throttling”?
  5. Laporan asli tentang masalah "stik USB macet"
  6. Batas kotor salah dihitung [2014]
  7. Pemblokiran alokasi halaman yang besar di IO [2011]
  8. “Halaman kotor mencapai akhir LRU”? [pra-2013]

1. Artikel 2013 salah

Artikel “USB-stick stall” memberi Anda kesan yang sangat menyesatkan. Ini salah menggambarkan laporan asli dan rangkaian tanggapan.

Artem tidak melaporkan seluruh sistem yang hang ketika di-flush cache menulis ke stik USB. Laporan aslinya hanya mengeluh bahwa menjalankan perintah "sinkronisasi" bisa memakan waktu hingga "puluhan menit". Perbedaan ini dibuat eksplisit dalam tanggapan oleh Linus Torvalds:

Sebenarnya sangat mudah untuk mereproduksi hanya dengan mengambil
kunci USB rata-rata Anda dan mencoba menulisnya. Saya baru saja melakukannya dengan gambar ISO
acak, dan itu menyakitkan. Dan itu tidak menyakitkan untuk melakukan
sebagian besar hal lain di latar belakang, tetapi jika Anda kebetulan menjalankan
apa pun yang melakukan "sinkronisasi" (dan itu terjadi dalam skrip), masalahnya hanya
terhenti.
Selama beberapa menit.

2. Kesalahan di LWN? Apakah Anda yakin?

Jon Corbet memiliki pengalaman lima belas tahun, melaporkan pengembangan kernel Linux setiap minggu. Saya berharap artikel itu setidaknya dekat untuk melakukannya dengan benar, dalam arti tertentu. Jadi saya ingin memproses dua catatan yang berbeda, dan mencari poin terperinci di mana mereka setuju atau tidak setuju.

Saya membaca semua diskusi asli, menggunakan arsip di lore.kernel.org. Saya rasa pesannya cukup jelas.

Saya 100% yakin artikel tersebut salah mengartikan diskusi. Dalam komentar di bawah artikel, setidaknya dua pembaca mengulangi klaim palsu dengan kata-kata mereka sendiri, dan tidak ada yang mengoreksinya. Artikel tersebut melanjutkan kebingungan ini di paragraf ketiga:

Semua data itu menyumbat antrian I/O, mungkin menunda operasi lain. Dan, segera setelah seseorang memanggil sync(), semuanya akan berhenti hingga seluruh antrean tersebut ditulis.

Ini bisa menjadi kebingungan dari Linus yang mengatakan "hal itu hanya berhenti melengking". “Benda” mengacu pada “apa pun yang sync “. Tapi Corbet menulis seolah-olah "benda itu" berarti "seluruh sistem".

Menurut Linus, ini adalah masalah dunia nyata. Tetapi sebagian besar "sesuatu" tidak panggilan ke dalam operasi sync() seluruh sistem.[1]

Mengapa Corbet membingungkan ini dengan "seluruh sistem"? Saya kira ada sejumlah masalah, dan setelah beberapa saat menjadi sulit untuk memisahkan semuanya di kepala Anda :-). Dan meskipun LWN telah menggambarkan pengembangan pelambatan kotor per-perangkat (dan per-proses), secara umum saya kira tidak banyak yang ditulis tentang detail seperti itu. Banyak dokumen hanya menjelaskan pengaturan batas kotor global.

3. Antrean panjang di perangkat I/O, yang dibuat oleh penulisan balik "latar belakang"

Artem memposting laporan kedua di utas, di mana “server hampir macet dan permintaan IO lainnya membutuhkan lebih banyak waktu untuk diselesaikan”.

Terkait:Linux – Merutekan melalui iptables?

Laporan kedua ini tidak sesuai dengan klaim tentang USB-stick hang. Itu terjadi setelah membuat file 10GB di internal disk. Ini adalah masalah yang berbeda.

Laporan itu tidak mengkonfirmasi apakah ini dapat ditingkatkan dengan mengubah batas kotor. Dan ada analisis yang lebih baru dari kasus seperti ini. Ada masalah yang signifikan ketika menyumbat antrian I/O dari disk utama Anda. Anda dapat mengalami penundaan yang lama pada disk yang selalu Anda andalkan, untuk memuat kode program sesuai permintaan, menyimpan dokumen dan data aplikasi menggunakan write() + fsync(), dll.

Menuju penulisan ulang latar belakang yang tidak terlalu mengganggu — LWN.net, 2016

Ketika kode manajemen memori memutuskan untuk menulis berbagai data kotor, hasilnya adalah permintaan I/O yang dikirimkan ke subsistem blok. Permintaan itu mungkin menghabiskan beberapa waktu di penjadwal I/O, tetapi akhirnya dikirim ke driver untuk perangkat tujuan.

Masalahnya adalah, jika ada banyak data kotor untuk ditulis, mungkin akan ada sejumlah besar (seperti dalam ribuan) permintaan yang antri untuk perangkat. Bahkan drive yang cukup cepat dapat membutuhkan waktu untuk mengerjakan banyak permintaan. Jika beberapa aktivitas lain (mengklik tautan di browser web, katakanlah, atau meluncurkan aplikasi) menghasilkan permintaan I/O pada perangkat blok yang sama, permintaan tersebut pergi ke belakang antrian panjang itu dan mungkin tidak dilayani untuk beberapa waktu. Jika beberapa, permintaan sinkron dibuat — kesalahan halaman dari aplikasi yang baru diluncurkan, misalnya — masing-masing permintaan tersebut, pada gilirannya, harus melewati antrean panjang ini. Itulah titik di mana segala sesuatunya tampak berhenti begitu saja.

[…]

Sebagian besar driver blok juga mempertahankan antrian mereka sendiri secara internal. Antrean tingkat yang lebih rendah dapat menjadi sangat bermasalah karena, pada saat permintaan sampai di sana, itu tidak lagi tunduk pada kontrol penjadwal I/O (jika ada penjadwal I/O sama sekali).

Tambalan digabungkan untuk meningkatkan ini pada akhir 2016 (Linux 4.10). Kode ini disebut sebagai “writeback throttling” atau WBT. Menelusuri web untuk wbt_lat_usec juga menemukan beberapa cerita lagi tentang ini. (Dokumen awal menulis tentang wb_lat_usec , tapi sudah ketinggalan zaman). Ketahuilah bahwa pembatasan tulis balik tidak berfungsi dengan penjadwal I/O CFQ atau BFQ. CFQ telah populer sebagai penjadwal I/O default, termasuk dalam pembuatan kernel default hingga Linux v4.20. CFQ dihapus di kernel v5.0.

Ada tes untuk menggambarkan masalah (dan solusi prototipe) pada SSD (yang tampak seperti NVMe) dan "hard drive biasa". Hard drive “tidak seburuk perangkat kedalaman antrian yang lebih dalam, di mana kami memiliki IO yang sangat cepat”.

Saya tidak yakin tentang "ribuan" permintaan yang antri, tetapi setidaknya ada perangkat NVMe yang dapat mengantre ratusan permintaan. Sebagian besar hard drive SATA memungkinkan 32 permintaan untuk diantrekan (“NCQ”). Tentu saja hard drive akan membutuhkan waktu lebih lama untuk menyelesaikan setiap permintaan.

4. Batasan “no-I/O dirty throttling”?

“No-I/O dirty throttling” adalah sistem rekayasa yang cukup rumit. Itu juga telah diubah dari waktu ke waktu. Saya yakin ada, dan masih ada, beberapa batasan di dalam kode ini.

Penulisan LWN, komentar kode/tambalan, dan slide dari presentasi terperinci menunjukkan bahwa sejumlah besar skenario telah dipertimbangkan. Ini termasuk stik USB lambat yang terkenal vs. penggerak utama yang cepat. Kasus uji mencakup frasa “1000 dd bersamaan” (yaitu penulis berurutan).

Sejauh ini, saya tidak tahu cara mendemonstrasikan dan mereproduksi batasan apa pun di dalam kode pembatasan yang kotor.

Saya telah melihat beberapa deskripsi perbaikan masalah yang berada di luar kode pelambatan yang kotor. Perbaikan terbaru yang saya temukan adalah pada tahun 2014 – lihat bagian selanjutnya. Di utas yang dilaporkan LWN, kami mempelajari:

Dalam beberapa rilis terakhir masalah seperti ini
disebabkan oleh masalah dalam reclaim yang muak dengan melihat banyak halaman writeback yang kotor
/ di bawah dan akhirnya macet menunggu IO selesai.

[…] Skrip systemtap menangkap jenis area tersebut dan saya
yakin bahwa area tersebut telah diperbaiki.

Mel Gorman juga mengatakan ada beberapa “masalah yang luar biasa”.

Masih ada masalah. Jika semua halaman kotor didukung oleh perangkat yang lambat, maka pembatasan kotor pada akhirnya akan menyebabkan kemacetan dalam penyeimbangan halaman kotor […]

Bagian ini adalah satu-satunya hal yang dapat saya temukan di utas diskusi yang dilaporkan, yang hampir mendukung interpretasi LWN. Saya berharap saya mengerti apa yang dimaksud :-(. Atau bagaimana cara mendemonstrasikannya, dan mengapa hal itu tampaknya tidak muncul sebagai masalah signifikan dalam pengujian yang dijalankan Artem dan Linus.

5. Laporan asli tentang masalah “USB-stick stall”

Meskipun baik Artem maupun Linux tidak melaporkan “USB-stick stall” yang mempengaruhi seluruh sistem, kami dapat menemukan beberapa laporan tentang ini di tempat lain. Ini termasuk laporan dalam beberapa tahun terakhir – jauh setelah perbaikan terakhir yang diketahui.

Saya tidak tahu apa perbedaannya. Mungkin kondisi pengujian mereka berbeda dalam beberapa hal, atau mungkin ada beberapa masalah baru yang dibuat di kernel sejak 2013…

  • https://utcc.utoronto.ca/~cks/space/blog/linux/USBDrivesKillMyPerformance / https://utcc.utoronto.ca/~cks/space/blog/linux/FixingUSBDriveResponsiveness [2017]
  • Mengapa PC saya membeku saat saya menyalin file ke flashdisk? [Januari 2014]
  • Sistem menjadi lambat saat melakukan operasi R/W besar pada disk eksternal [2018]
  • Linux GUI menjadi sangat tidak responsif saat melakukan I/O hard disk – apa yang harus disetel? [2019]

6. Batas kotor salah dihitung [2014]

Ada perbaikan menarik pada Januari 2014 (diterapkan di kernel v3.14). Dalam pertanyaan, kami mengatakan batas default diatur ke 20% dari memori. Sebenarnya, ini diatur ke 20% dari memori yang tersedia untuk cache halaman kotor. Misalnya buffer kernel mengirim data untuk soket jaringan TCP/IP. Buffer soket tidak dapat dihapus dan diganti dengan cache halaman kotor :-).

Masalahnya adalah kernel menghitung memori yang dapat ditukar, seolah-olah dapat menukar data demi cache halaman kotor. Meskipun ini mungkin secara teori, kernel sangat bias untuk menghindari swapping, dan lebih memilih menjatuhkan cache halaman sebagai gantinya. Masalah ini diilustrasikan oleh – coba tebak – pengujian yang melibatkan penulisan ke stik USB yang lambat, dan menyadari bahwa hal itu menyebabkan kemacetan di seluruh sistem :-).

Terkait:Linux – Mengapa mengalihkan output ke 2>&1 dan 1>&2?

Lihat Re:[patch 0/2] mm:kurangi reclaim stalls dengan anon berat dan cache kotor

Cara mengatasinya adalah dirty_ratio sekarang diperlakukan sebagai bagian dari cache file saja.

Menurut pengembang kernel yang mengalami masalah, “kondisi pemicu tampaknya cukup masuk akal – penggunaan memori tinggi dengan buffer IO berat dan konfigurasi swap – dan kemungkinan besar ini terjadi di alam liar.” Jadi ini mungkin menjelaskan beberapa laporan pengguna sekitar tahun 2013 atau sebelumnya.

7. Pemblokiran alokasi halaman yang besar di IO [2011]

Ini adalah masalah lain:Halaman besar, drive lambat, dan penundaan lama (LWN.net, November 2011). Masalah dengan halaman besar ini sekarang harus diperbaiki.

Selain itu, terlepas dari apa yang dikatakan artikel tersebut, saya pikir sebagian besar PC Linux saat ini tidak benar-benar menggunakan halaman yang besar. Ini mungkin berubah mulai dari Debian 10. Namun, meskipun Debian 10 mulai mengalokasikan halaman besar jika memungkinkan, tampak jelas bagi saya bahwa itu tidak akan menyebabkan penundaan, kecuali jika Anda mengubah pengaturan lain yang disebut defrag untuk "selalu".

8. “Halaman kotor mencapai akhir LRU” [pra-2013]

Saya belum memeriksanya, tetapi menurut saya ini menarik:

mgorman 2011:Ini adalah jenis baru dari kios terkait USB karena karena penulisan pemadatan sinkron dimana seperti di masa lalu masalah besar adalah halaman kotor
mencapai akhir LRU dan sedang ditulis oleh reclaim .

mgorman 2013:Pekerjaan di area umum tersebut menangani
masalah seperti halaman kotor yang mencapai akhir LRU (penggunaan CPU
yang berlebihan)

Jika ini adalah dua masalah "mencapai akhir dari LRU" yang berbeda, maka yang pertama terdengar seperti itu bisa sangat buruk. Kedengarannya seperti ketika halaman kotor menjadi halaman yang paling jarang digunakan, setiap upaya untuk mengalokasikan memori akan tertunda, hingga halaman kotor itu selesai ditulis.

Apa pun artinya, dia mengatakan masalahnya sekarang sudah diperbaiki.

[1] Satu pengecualian:untuk sementara, manajer paket Debian dpkg menggunakan sync() untuk meningkatkan kinerja. Ini telah dihapus, karena masalah persisnya yang sync() bisa memakan waktu sangat lama. Mereka beralih ke pendekatan menggunakan sync_file_range() di Linux. Lihat bug Ubuntu #624877, komentar 62.

Bagian dari upaya sebelumnya untuk menjawab pertanyaan ini – ini sebagian besar harus berlebihan:

Saya rasa kami dapat menjelaskan bahwa kedua laporan Artem konsisten dengan kode “No-I/O dirty throttling”.

Kode pelambatan kotor bertujuan untuk memungkinkan setiap perangkat pendukung mendapatkan bagian yang adil dari "total write-back cache", "yang terkait dengan kecepatan penulisan rata-rata saat ini dalam kaitannya dengan perangkat lain". Ungkapan ini berasal dari dokumentasi /sys/class/bdi/.[2]

Dalam kasus yang paling sederhana, hanya satu perangkat pendukung yang digunakan untuk menulis. Dalam hal ini, bagian yang adil dari perangkat adalah 100%. write() panggilan dibatasi untuk mengontrol cache writeback secara keseluruhan, dan menjaganya pada "setpoint".

Penulisan mulai dibatasi setengah jalan antara dirty_background_ratio – titik yang memulai penulisan latar belakang – dan dirty_ratio – batas keras pada cache writeback. Secara default, ini adalah 10% dan 20% dari memori yang tersedia.

Misalnya, Anda masih bisa mengisi hingga 15% penulisan ke disk utama Anda saja. Anda dapat memiliki gigabyte penulisan cache, sesuai dengan berapa banyak RAM yang Anda miliki. Pada saat itu, panggilan write() akan mulai dibatasi agar sesuai dengan kecepatan writeback – tapi itu tidak masalah. Saya berharap masalah hang adalah untuk panggilan read() dan fsync() , yang macet di belakang sejumlah besar IO yang tidak terkait. Ini adalah masalah khusus yang ditangani oleh kode "pembatasan penulisan balik". Beberapa pengiriman tambalan WBT menyertakan deskripsi masalah, yang menunjukkan penundaan mengerikan yang disebabkan oleh hal ini.

Demikian pula, Anda dapat mengisi 15% seluruhnya dengan menulis ke stik USB. Write()s lebih lanjut ke USB akan dibatasi. Tetapi disk utama tidak akan menggunakan bagiannya yang adil. Jika Anda mulai memanggil write() pada sistem file utama Anda, maka itu tidak akan dibatasi, atau setidaknya akan tertunda apalagi. Dan menurut saya USB write() akan lebih diperketat lagi, untuk menyeimbangkan kedua penulis.

Saya berharap cache writeback keseluruhan untuk sementara dapat naik di atas setpoint. Dalam beberapa kasus yang lebih menuntut, Anda dapat mencapai batas keras pada cache tulis balik secara keseluruhan. Batas keras default ke 20% dari memori yang tersedia; opsi konfigurasinya adalah dirty_ratio / dirty_bytes . Mungkin Anda dapat menekan ini karena perangkat dapat melambat (mungkin karena pola I/O yang lebih acak), dan pelambatan kotor tidak segera mengenali perubahan kecepatan.

[2] Anda mungkin memperhatikan bahwa dokumen ini menyarankan Anda untuk secara manual batasi proporsi cache writeback, yang dapat digunakan untuk partisi/sistem file tertentu. Pengaturannya disebut /sys/class/bdi/*/max_ratio . Ketahuilah bahwa “jika perangkat yang ingin Anda batasi adalah satu-satunya yang saat ini digunakan untuk menulis, pembatasan tidak akan berpengaruh besar”.


Linux
  1. Periksa Beban Sistem di Linux

  2. Bagian mana dari kode rakitan HelloWorld ini yang penting jika saya menulis program dalam rakitan?

  3. Linux:'Username' tidak ada dalam file sudoers. Kejadian ini akan dilaporkan

  1. Cara memeriksa Versi OS dan Linux

  2. Pemecahan masalah Linux 101:Kinerja sistem

  3. Mengapa penggunaan CPU dilaporkan oleh top di Linux lebih dari 100%?

  1. Bagaimana mengubah identitas sistem Linux

  2. Linux – Mengapa Utils Linux Tidak Menggunakan System Call Untuk Mendapatkan Waktu Saat Ini?

  3. Mengapa Perintah Berikut Membunuh Sistem?