€•G9Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ9/translations/zh_CN/filesystems/bcachefs/future/idle_work”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ9/translations/zh_TW/filesystems/bcachefs/future/idle_work”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ9/translations/it_IT/filesystems/bcachefs/future/idle_work”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ9/translations/ja_JP/filesystems/bcachefs/future/idle_work”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ9/translations/ko_KR/filesystems/bcachefs/future/idle_work”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ9/translations/sp_SP/filesystems/bcachefs/future/idle_work”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒ paragraph”“”)”}”(hŒ(Idle/background work classes design doc:”h]”hŒ(Idle/background work classes design doc:”…””}”(hh£hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸŒS/var/lib/git/docbuild/linux/Documentation/filesystems/bcachefs/future/idle_work.rst”h Khhhžhubh¢)”}”(hX Right now, our behaviour at idle isn't ideal, it was designed for servers that would be under sustained load, to keep pending work at a "medium" level, to let work build up so we can process it in more efficient batches, while also giving headroom for bursts in load.”h]”hXRight now, our behaviour at idle isn’t ideal, it was designed for servers that would be under sustained load, to keep pending work at a “medium†level, to let work build up so we can process it in more efficient batches, while also giving headroom for bursts in load.”…””}”(hh²hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h Khhhžhubh¢)”}”(hXBut for desktops or mobile - scenarios where work is less sustained and power usage is more important - we want to operate differently, with a "rush to idle" so the system can go to sleep. We don't want to be dribbling out background work while the system should be idle.”h]”hXBut for desktops or mobile - scenarios where work is less sustained and power usage is more important - we want to operate differently, with a “rush to idle†so the system can go to sleep. We don’t want to be dribbling out background work while the system should be idle.”…””}”(hhÀhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h Khhhžhubh¢)”}”(hŒÅThe complicating factor is that there are a number of background tasks, which form a heirarchy (or a digraph, depending on how you divide it up) - one background task may generate work for another.”h]”hŒÅThe complicating factor is that there are a number of background tasks, which form a heirarchy (or a digraph, depending on how you divide it up) - one background task may generate work for another.”…””}”(hhÎhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K hhhžhubh¢)”}”(hŒ9Thus proper idle detection needs to model this heirarchy.”h]”hŒ9Thus proper idle detection needs to model this heirarchy.”…””}”(hhÜhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h KhhhžhubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒForeground writes”h]”h¢)”}”(hhóh]”hŒForeground writes”…””}”(hhõhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h Khhñubah}”(h]”h ]”h"]”h$]”h&]”uh1hïhhìhžhhŸh±h Nubhð)”}”(hŒPage cache writeback”h]”h¢)”}”(hj h]”hŒPage cache writeback”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1hïhhìhžhhŸh±h Nubhð)”}”(hŒCopygc, rebalance”h]”h¢)”}”(hj!h]”hŒCopygc, rebalance”…””}”(hj#hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1hïhhìhžhhŸh±h Nubhð)”}”(hŒJournal reclaim ”h]”h¢)”}”(hŒJournal reclaim”h]”hŒJournal reclaim”…””}”(hj:hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h Khj6ubah}”(h]”h ]”h"]”h$]”h&]”uh1hïhhìhžhhŸh±h Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1hêhŸh±h Khhhžhubh¢)”}”(hX,When we implement idle detection and rush to idle, we need to be careful not to disturb too much the existing behaviour that works reasonably well when the system is under sustained load (or perhaps improve it in the case of rebalance, which currently does not actively attempt to let work batch up).”h]”hX,When we implement idle detection and rush to idle, we need to be careful not to disturb too much the existing behaviour that works reasonably well when the system is under sustained load (or perhaps improve it in the case of rebalance, which currently does not actively attempt to let work batch up).”…””}”(hjVhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h KhhhžhubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒSUSTAINED LOAD REGIME”h]”hŒSUSTAINED LOAD REGIME”…””}”(hjkhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jihjfhžhhŸh±h Kubh¢)”}”(hXWhen the system is under continuous load, we want these jobs to run continuously - this is perhaps best modelled with a P/D controller, where they'll be trying to keep a target value (i.e. fragmented disk space, available journal space) roughly in the middle of some range.”h]”hXWhen the system is under continuous load, we want these jobs to run continuously - this is perhaps best modelled with a P/D controller, where they’ll be trying to keep a target value (i.e. fragmented disk space, available journal space) roughly in the middle of some range.”…””}”(hjyhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K hjfhžhubh¢)”}”(hŒîThe goal under sustained load is to balance our ability to handle load spikes without running out of x resource (free disk space, free space in the journal), while also letting some work accumululate to be batched (or become unnecessary).”h]”hŒîThe goal under sustained load is to balance our ability to handle load spikes without running out of x resource (free disk space, free space in the journal), while also letting some work accumululate to be batched (or become unnecessary).”…””}”(hj‡hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K%hjfhžhubh¢)”}”(hXzFor example, we don't want to run copygc too aggressively, because then it will be evacuating buckets that would have become empty (been overwritten or deleted) anyways, and we don't want to wait until we're almost out of free space because then the system will behave unpredicably - suddenly we're doing a lot more work to service each write and the system becomes much slower.”h]”hX‚For example, we don’t want to run copygc too aggressively, because then it will be evacuating buckets that would have become empty (been overwritten or deleted) anyways, and we don’t want to wait until we’re almost out of free space because then the system will behave unpredicably - suddenly we’re doing a lot more work to service each write and the system becomes much slower.”…””}”(hj•hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K*hjfhžhubeh}”(h]”Œsustained-load-regime”ah ]”h"]”Œsustained load regime”ah$]”h&]”uh1jdhhhžhhŸh±h Kubje)”}”(hhh]”(jj)”}”(hŒ IDLE REGIME”h]”hŒ IDLE REGIME”…””}”(hj®hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jihj«hžhhŸh±h K1ubh¢)”}”(hŒnWhen the system becomes idle, we should start flushing our pending work quicker so the system can go to sleep.”h]”hŒnWhen the system becomes idle, we should start flushing our pending work quicker so the system can go to sleep.”…””}”(hj¼hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K3hj«hžhubh¢)”}”(hŒ·Note that the definition of "idle" depends on where in the heirarchy a task is - a task should start flushing work more quickly when the task above it has stopped generating new work.”h]”hŒ»Note that the definition of “idle†depends on where in the heirarchy a task is - a task should start flushing work more quickly when the task above it has stopped generating new work.”…””}”(hjÊhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K6hj«hžhubh¢)”}”(hŒ¹e.g. rebalance should start flushing more quickly when page cache writeback is idle, and journal reclaim should only start flushing more quickly when both copygc and rebalance are idle.”h]”hŒ¹e.g. rebalance should start flushing more quickly when page cache writeback is idle, and journal reclaim should only start flushing more quickly when both copygc and rebalance are idle.”…””}”(hjØhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K:hj«hžhubh¢)”}”(hX:It's important to let work accumulate when more work is still incoming and we still have room, because flushing is always more efficient if we let it batch up. New writes may overwrite data before rebalance moves it, and tasks may be generating more updates for the btree nodes that journal reclaim needs to flush.”h]”hX<It’s important to let work accumulate when more work is still incoming and we still have room, because flushing is always more efficient if we let it batch up. New writes may overwrite data before rebalance moves it, and tasks may be generating more updates for the btree nodes that journal reclaim needs to flush.”…””}”(hjæhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h K>hj«hžhubh¢)”}”(hX‚On idle, how much work we do at each interval should be proportional to the length of time we have been idle for. If we're idle only for a short duration, we shouldn't flush everything right away; the system might wake up and start generating new work soon, and flushing immediately might end up doing a lot of work that would have been unnecessary if we'd allowed things to batch more.”h]”hXˆOn idle, how much work we do at each interval should be proportional to the length of time we have been idle for. If we’re idle only for a short duration, we shouldn’t flush everything right away; the system might wake up and start generating new work soon, and flushing immediately might end up doing a lot of work that would have been unnecessary if we’d allowed things to batch more.”…””}”(hjôhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h KChj«hžhubh¢)”}”(hŒTo summarize, we will need:”h]”hŒTo summarize, we will need:”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h KIhj«hžhubhŒ block_quote”“”)”}”(hX- A list of classes for background tasks that generate work, which will include one "foreground" class. - Tracking for each class - "Am I doing work, or have I gone to sleep?" - And each class should check the class above it when deciding how much work to issue.”h]”hë)”}”(hhh]”(hð)”}”(hŒeA list of classes for background tasks that generate work, which will include one "foreground" class.”h]”h¢)”}”(hŒeA list of classes for background tasks that generate work, which will include one "foreground" class.”h]”hŒiA list of classes for background tasks that generate work, which will include one “foreground†class.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h KKhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hïhjubhð)”}”(hŒETracking for each class - "Am I doing work, or have I gone to sleep?"”h]”h¢)”}”(hj3h]”hŒITracking for each class - “Am I doing work, or have I gone to sleep?—…””}”(hj5hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h KMhj1ubah}”(h]”h ]”h"]”h$]”h&]”uh1hïhjubhð)”}”(hŒTAnd each class should check the class above it when deciding how much work to issue.”h]”h¢)”}”(hjJh]”hŒTAnd each class should check the class above it when deciding how much work to issue.”…””}”(hjLhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hŸh±h KNhjHubah}”(h]”h ]”h"]”h$]”h&]”uh1hïhjubeh}”(h]”h ]”h"]”h$]”h&]”jTjUuh1hêhŸh±h KKhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhŸh±h KKhj«hžhubeh}”(h]”Œ idle-regime”ah ]”h"]”Œ idle regime”ah$]”h&]”uh1jdhhhžhhŸh±h K1ubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h±uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(jiNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j–Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”h±Œ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j¨j¥jpjmuŒ nametypes”}”(j¨‰jp‰uh}”(j¥jfjmj«uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.