€•Å=Œ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”Œ"/translations/zh_CN/fb/deferred_io”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ"/translations/zh_TW/fb/deferred_io”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ"/translations/it_IT/fb/deferred_io”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ"/translations/ja_JP/fb/deferred_io”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ"/translations/ko_KR/fb/deferred_io”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ"/translations/sp_SP/fb/deferred_io”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ Deferred IO”h]”hŒ Deferred IO”…””}”(hh¨hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hh£hžhhŸŒdeferred IO and driver sets up fault and page_mkwrite handlers”h]”h¸)”}”(hhçh]”hŒ>deferred IO and driver sets up fault and page_mkwrite handlers”…””}”(hhéhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K hhåubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ0userspace app tries to write to mmapped vaddress”h]”h¸)”}”(hhþh]”hŒ0userspace app tries to write to mmapped vaddress”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K hhüubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ(we get pagefault and reach fault handler”h]”h¸)”}”(hjh]”hŒ(we get pagefault and reach fault handler”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ-fault handler finds and returns physical page”h]”h¸)”}”(hj,h]”hŒ-fault handler finds and returns physical page”…””}”(hj.hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khj*ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ4we get page_mkwrite where we add this page to a list”h]”h¸)”}”(hjCh]”hŒ4we get page_mkwrite where we add this page to a list”…””}”(hjEhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KhjAubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ1schedule a workqueue task to be run after a delay”h]”h¸)”}”(hjZh]”hŒ1schedule a workqueue task to be run after a delay”…””}”(hj\hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KhjXubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒTapp continues writing to that page with no additional cost. this is the key benefit.”h]”h¸)”}”(hŒTapp continues writing to that page with no additional cost. this is the key benefit.”h]”hŒTapp continues writing to that page with no additional cost. this is the key benefit.”…””}”(hjshžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khjoubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ®the workqueue task comes in and mkcleans the pages on the list, then completes the work associated with updating the framebuffer. this is the real work talking to the device.”h]”h¸)”}”(hŒ®the workqueue task comes in and mkcleans the pages on the list, then completes the work associated with updating the framebuffer. this is the real work talking to the device.”h]”hŒ®the workqueue task comes in and mkcleans the pages on the list, then completes the work associated with updating the framebuffer. this is the real work talking to the device.”…””}”(hj‹hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khj‡ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ?app tries to write to the address (that has now been mkcleaned)”h]”h¸)”}”(hj¡h]”hŒ?app tries to write to the address (that has now been mkcleaned)”…””}”(hj£hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KhjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h NubhÍ)”}”(hŒ2get pagefault and the above sequence occurs again ”h]”h¸)”}”(hŒ1get pagefault and the above sequence occurs again”h]”hŒ1get pagefault and the above sequence occurs again”…””}”(hjºhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khj¶ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÌhhÉhžhhŸh¶h Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1hÇhŸh¶h K hh£hžhubh¸)”}”(hXAs can be seen from above, one benefit is roughly to allow bursty framebuffer writes to occur at minimum cost. Then after some time when hopefully things have gone quiet, we go and really update the framebuffer which would be a relatively more expensive operation.”h]”hXAs can be seen from above, one benefit is roughly to allow bursty framebuffer writes to occur at minimum cost. Then after some time when hopefully things have gone quiet, we go and really update the framebuffer which would be a relatively more expensive operation.”…””}”(hjÖhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hŒÄFor some types of nonvolatile high latency displays, the desired image is the final image rather than the intermediate stages which is why it's okay to not update for each write that is occurring.”h]”hŒÆFor some types of nonvolatile high latency displays, the desired image is the final image rather than the intermediate stages which is why it’s okay to not update for each write that is occurring.”…””}”(hjähžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hŒÖIt may be the case that this is useful in other scenarios as well. Paul Mundt has mentioned a case where it is beneficial to use the page count to decide whether to coalesce and issue SG DMA or to do memory bursts.”h]”hŒÖIt may be the case that this is useful in other scenarios as well. Paul Mundt has mentioned a case where it is beneficial to use the page count to decide whether to coalesce and issue SG DMA or to do memory bursts.”…””}”(hjòhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K"hh£hžhubh¸)”}”(hXAnother one may be if one has a device framebuffer that is in an usual format, say diagonally shifting RGB, this may then be a mechanism for you to allow apps to pretend to have a normal framebuffer but reswizzle for the device framebuffer at vsync time based on the touched pagelist.”h]”hXAnother one may be if one has a device framebuffer that is in an usual format, say diagonally shifting RGB, this may then be a mechanism for you to allow apps to pretend to have a normal framebuffer but reswizzle for the device framebuffer at vsync time based on the touched pagelist.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K&hh£hžhubh¢)”}”(hhh]”(h§)”}”(hŒ!How to use it: (for applications)”h]”hŒ!How to use it: (for applications)”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h K,ubh¸)”}”(hŒDNo changes needed. mmap the framebuffer like normal and just use it.”h]”hŒDNo changes needed. mmap the framebuffer like normal and just use it.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K-hjhžhubeh}”(h]”Œhow-to-use-it-for-applications”ah ]”h"]”Œ!how to use it: (for applications)”ah$]”h&]”uh1h¡hh£hžhhŸh¶h K,ubh¢)”}”(hhh]”(h§)”}”(hŒ"How to use it: (for fbdev drivers)”h]”hŒ"How to use it: (for fbdev drivers)”…””}”(hj8hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj5hžhhŸh¶h K0ubh¸)”}”(hŒ%The following example may be helpful.”h]”hŒ%The following example may be helpful.”…””}”(hjFhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K1hj5hžhubhŒenumerated_list”“”)”}”(hhh]”hÍ)”}”(hŒµSetup your structure. Eg:: static struct fb_deferred_io hecubafb_defio = { .delay = HZ, .deferred_io = hecubafb_dpy_deferred_io, }; ”h]”(h¸)”}”(hŒSetup your structure. Eg::”h]”hŒSetup your structure. Eg:”…””}”(hj]hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K3hjYubhŒ literal_block”“”)”}”(hŒ„static struct fb_deferred_io hecubafb_defio = { .delay = HZ, .deferred_io = hecubafb_dpy_deferred_io, };”h]”hŒ„static struct fb_deferred_io hecubafb_defio = { .delay = HZ, .deferred_io = hecubafb_dpy_deferred_io, };”…””}”hjmsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jkhŸh¶h K5hjYubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÌhjVhžhhŸh¶h Nubah}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1jThj5hžhhŸh¶h K3ubh¸)”}”(hŒ¥The delay is the minimum delay between when the page_mkwrite trigger occurs and when the deferred_io callback is called. The deferred_io callback is explained below.”h]”hŒ¥The delay is the minimum delay between when the page_mkwrite trigger occurs and when the deferred_io callback is called. The deferred_io callback is explained below.”…””}”(hjŽhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K:hj5hžhubjU)”}”(hhh]”hÍ)”}”(hŒ­Setup your deferred IO callback. Eg:: static void hecubafb_dpy_deferred_io(struct fb_info *info, struct list_head *pagelist) ”h]”(h¸)”}”(hŒ%Setup your deferred IO callback. Eg::”h]”hŒ$Setup your deferred IO callback. Eg:”…””}”(hj£hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K>hjŸubjl)”}”(hŒ{static void hecubafb_dpy_deferred_io(struct fb_info *info, struct list_head *pagelist)”h]”hŒ{static void hecubafb_dpy_deferred_io(struct fb_info *info, struct list_head *pagelist)”…””}”hj±sbah}”(h]”h ]”h"]”h$]”h&]”j{j|uh1jkhŸh¶h K@hjŸubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÌhjœhžhhŸh¶h Nubah}”(h]”h ]”h"]”h$]”h&]”j‰jŠj‹hjŒjŒstart”Kuh1jThj5hžhhŸh¶h K>ubh¸)”}”(hŒúThe deferred_io callback is where you would perform all your IO to the display device. You receive the pagelist which is the list of pages that were written to during the delay. You must not modify this list. This callback is called from a workqueue.”h]”hŒúThe deferred_io callback is where you would perform all your IO to the display device. You receive the pagelist which is the list of pages that were written to during the delay. You must not modify this list. This callback is called from a workqueue.”…””}”(hjÌhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KChj5hžhubjU)”}”(hhh]”(hÍ)”}”(hŒSCall init:: info->fbdefio = &hecubafb_defio; fb_deferred_io_init(info); ”h]”(h¸)”}”(hŒ Call init::”h]”hŒ Call init:”…””}”(hjáhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KHhjÝubjl)”}”(hŒ;info->fbdefio = &hecubafb_defio; fb_deferred_io_init(info);”h]”hŒ;info->fbdefio = &hecubafb_defio; fb_deferred_io_init(info);”…””}”hjïsbah}”(h]”h ]”h"]”h$]”h&]”j{j|uh1jkhŸh¶h KJhjÝubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÌhjÚhžhhŸh¶h NubhÍ)”}”(hŒ2Call cleanup:: fb_deferred_io_cleanup(info);”h]”(h¸)”}”(hŒCall cleanup::”h]”hŒ Call cleanup:”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KMhjubjl)”}”(hŒfb_deferred_io_cleanup(info);”h]”hŒfb_deferred_io_cleanup(info);”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”j{j|uh1jkhŸh¶h KOhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÌhjÚhžhhŸh¶h Nubeh}”(h]”h ]”h"]”h$]”h&]”j‰jŠj‹hjŒjjËKuh1jThj5hžhhŸh¶h KHubeh}”(h]”Œhow-to-use-it-for-fbdev-drivers”ah ]”h"]”Œ"how to use it: (for fbdev drivers)”ah$]”h&]”uh1h¡hh£hžhhŸh¶h K0ubeh}”(h]”Œ deferred-io”ah ]”h"]”Œ deferred io”ah$]”h&]”uh1h¡hhhžhhŸh¶h Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h¶uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(h¦NŒ 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”jbŒ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<j9j2j/j4j1uŒ nametypes”}”(j<‰j2‰j4‰uh}”(j9h£j/jj1j5uŒ 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”]”(hŒsystem_message”“”)”}”(hhh]”h¸)”}”(hŒ:Enumerated list start value not ordinal-1: "2" (ordinal 2)”h]”hŒ>Enumerated list start value not ordinal-1: “2†(ordinal 2)”…””}”(hjÉhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hjÆubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œsource”h¶Œline”Kuh1jÄhj5hžhhŸh¶h K>ubjÅ)”}”(hhh]”h¸)”}”(hŒ:Enumerated list start value not ordinal-1: "3" (ordinal 3)”h]”hŒ>Enumerated list start value not ordinal-1: “3†(ordinal 3)”…””}”(hjåhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hjâubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”jߌsource”h¶Œline”Kuh1jÄhj5hžhhŸh¶h KHubeŒtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.