{"id":4419,"date":"2018-11-19T13:34:55","date_gmt":"2018-11-19T03:34:55","guid":{"rendered":"https:\/\/www.flamingspork.com\/blog\/?p=4419"},"modified":"2018-11-19T13:35:09","modified_gmt":"2018-11-19T03:35:09","slug":"tracing-flash-reads-and-writes-during-boot","status":"publish","type":"post","link":"https:\/\/www.flamingspork.com\/blog\/2018\/11\/19\/tracing-flash-reads-and-writes-during-boot\/","title":{"rendered":"Tracing flash reads (and writes) during boot"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">On OpenPOWER POWER9 systems, we typically talk to the flash chips that hold firmware for the host (i.e. the POWER9) processor through a daemon running on the BMC (aka service processor) rather than directly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We have host firmware map &#8220;windows&#8221; on the LPC bus to parts of the flash chip. This flash chip can in fact be a virtual one, constructed dynamically from files on the BMC.<br \/><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since we&#8217;re mapping windows into this flash address space, we have some knowledge as to what IO the host is doing to\/from the pnor. We can use this to output data in the blktrace format and feed into existing tools used to analyze IO patterns.<br \/><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, with a bit of learning of the data format and learning how to drive the various tools, I was ready to patch the BMC daemon (mboxbridge) to get some data out.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An initial bit of data is a graph of the windows into PNOR opened up during an normal boot (see below).<br \/><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"1077\" data-attachment-id=\"4420\" data-permalink=\"https:\/\/www.flamingspork.com\/blog\/2018\/11\/19\/tracing-flash-reads-and-writes-during-boot\/wionormalipl\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wionormalipl.png?fit=1044%2C1926&amp;ssl=1\" data-orig-size=\"1044,1926\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"wionormalipl\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wionormalipl.png?fit=555%2C1024&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wionormalipl.png?resize=584%2C1077&#038;ssl=1\" alt=\"\" class=\"wp-image-4420\" srcset=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wionormalipl.png?w=1044&amp;ssl=1 1044w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wionormalipl.png?resize=163%2C300&amp;ssl=1 163w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wionormalipl.png?resize=768%2C1417&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wionormalipl.png?resize=555%2C1024&amp;ssl=1 555w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><figcaption>PNOR windows created over the course of a normal boot.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This shows us that over the course of the boot, we open a bunch of windows, and switch them around a fair bit early on. This makes sense as early in boot we do not yet have DRAM working and page in firmware on-demand into L3 cache.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Later in boot, you can see the loading of larger chunks of firmware into memory. It&#8217;s also possible to see that this seems to take longer than it should &#8211; and indeed, we have a bug there.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, by modifying the code again, I introduced recording of when we used a window that the BMC had already cached. While the host will only see one window at a time, the BMC can keep around the ones it prepared earlier in order to avoid IO to the actual flash chips (which are SPI flash, so aren&#8217;t incredibly fast).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here we can see that we&#8217;re likely not doing the most efficient things during boot, and there&#8217;s probably room for some optimization.<br \/><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"1077\" data-attachment-id=\"4421\" data-permalink=\"https:\/\/www.flamingspork.com\/blog\/2018\/11\/19\/tracing-flash-reads-and-writes-during-boot\/dupewindows\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/dupewindows.png?fit=1044%2C1926&amp;ssl=1\" data-orig-size=\"1044,1926\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"dupewindows\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/dupewindows.png?fit=555%2C1024&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/dupewindows.png?resize=584%2C1077&#038;ssl=1\" alt=\"\" class=\"wp-image-4421\" srcset=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/dupewindows.png?w=1044&amp;ssl=1 1044w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/dupewindows.png?resize=163%2C300&amp;ssl=1 163w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/dupewindows.png?resize=768%2C1417&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/dupewindows.png?resize=555%2C1024&amp;ssl=1 555w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><figcaption>Normal boot but including re-used Windows rather than just created ones<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, in order to get finer grained information, I reduced the window size from one megabyte down to 4096 bytes. This will impose a heavy speed penalty as it&#8217;ll mean we will have to create a <strong>lot<\/strong> more windows to do the same amount of IO, but it means that since we&#8217;re using the page size of hostboot, we&#8217;ll see each individual page in\/out operation that it does during boot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, from the next graph, we can see that there&#8217;s several &#8220;hot&#8221; areas of the image, and on the whole it&#8217;s not too many pages. This gives us a hint that a bit of effort to reduce binary image size a little bit could greatly reduce the amount of IO we have to do.<br \/><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"1077\" data-attachment-id=\"4422\" data-permalink=\"https:\/\/www.flamingspork.com\/blog\/2018\/11\/19\/tracing-flash-reads-and-writes-during-boot\/4096bytewindowtrace\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/4096bytewindowtrace.png?fit=1044%2C1926&amp;ssl=1\" data-orig-size=\"1044,1926\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"4096bytewindowtrace\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/4096bytewindowtrace.png?fit=555%2C1024&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/4096bytewindowtrace.png?resize=584%2C1077&#038;ssl=1\" alt=\"\" class=\"wp-image-4422\" srcset=\"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/4096bytewindowtrace.png?w=1044&amp;ssl=1 1044w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/4096bytewindowtrace.png?resize=163%2C300&amp;ssl=1 163w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/4096bytewindowtrace.png?resize=768%2C1417&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/4096bytewindowtrace.png?resize=555%2C1024&amp;ssl=1 555w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><figcaption>4096 byte (i.e. page) size window, capturing the bits of flash we need to read in several times due to being low on memory when we&#8217;re L3 cache constrained.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The iowatcher tool also can construct a <strong>video<\/strong> of the boot and what &#8220;blocks&#8221; are being read.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"564\" style=\"aspect-ratio: 1246 \/ 564;\" width=\"1246\" controls src=\"https:\/\/www.flamingspork.com\/blog\/wp-content\/uploads\/2018\/11\/wio82ipl-full-rect.ogv\"><\/video><figcaption>Video of what blocks are read from flash during booting<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">So, what do we get from this adventure? Well, we get a good list of things to look into in order to improve boot performance, and we get to back these up with data rather than guesswork. Since this also works on unmodified host firmware, we&#8217;re measuring what we really boot rather than changing it in order to measure it.<br \/><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What you need to reproduce this:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/gerrit.openbmc-project.xyz\/c\/openbmc\/mboxbridge\/+\/15959\">mboxbridge patch is up in OpenBMC Gerrit<\/a><\/li><li><a href=\"http:\/\/masoncoding.com\/iowatcher\/\">blkparse(1)<\/a> man page<\/li><li>Chris Mason&#8217;s <a href=\"http:\/\/masoncoding.com\/iowatcher\/\">iowatcher<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>On OpenPOWER POWER9 systems, we typically talk to the flash chips that hold firmware for the host (i.e. the POWER9) processor through a daemon running on the BMC (aka service processor) rather than directly. We have host firmware map &#8220;windows&#8221; &hellip; <a href=\"https:\/\/www.flamingspork.com\/blog\/2018\/11\/19\/tracing-flash-reads-and-writes-during-boot\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[76,570,615],"tags":[738,586,585,141,636,656,587],"class_list":["post-4419","post","type-post","status-publish","format-standard","hentry","category-code","category-ibm-work-et-al","category-powerpc","tag-blktrace","tag-firmware","tag-hostboot","tag-linux","tag-opal","tag-openbmc","tag-openpower"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5a6n8-19h","jetpack-related-posts":[{"id":4508,"url":"https:\/\/www.flamingspork.com\/blog\/2019\/12\/10\/looking-at-the-state-of-blackbird-firmware\/","url_meta":{"origin":4419,"position":0},"title":"Looking at the state of Blackbird firmware","author":"Stewart Smith","date":"2019-12-10","format":false,"excerpt":"Having been somewhat involved in OpenPOWER firmware, I have a bunch of experience and opinions on maintaining firmware trees for products, what working with upstream looks like and all that. So, with my new Blackbird system I decided to take a bit of a look as to what the firmware\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4440,"url":"https:\/\/www.flamingspork.com\/blog\/2019\/01\/23\/cve-2019-6260-gaining-control-of-bmc-from-the-host-processor\/","url_meta":{"origin":4419,"position":1},"title":"CVE-2019-6260: Gaining control of BMC from the host processor","author":"Stewart Smith","date":"2019-01-23","format":false,"excerpt":"This is details for CVE-2019-6260 - which has been nicknamed \"pantsdown\" due to the nature of feeling that we feel that we've \"caught chunks of the industry with their...\" and combined with the fact that naming things is hard, so if you pick a bad name somebody would have to\u2026","rel":"","context":"In &quot;General&quot;","block_context":{"text":"General","link":"https:\/\/www.flamingspork.com\/blog\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4072,"url":"https:\/\/www.flamingspork.com\/blog\/2016\/06\/20\/building-opal-firmware-for-power9\/","url_meta":{"origin":4419,"position":2},"title":"Building OPAL firmware for POWER9","author":"Stewart Smith","date":"2016-06-20","format":false,"excerpt":"Recently, we merged into the op-build project (the build scripts for OpenPOWER Firmware) a defconfig for building OPAL for (certain) POWER9 simulators. I won't bother linking over to articles on the POWER9 chip or schedule (there's search engines for that), but with this commit - if you happen to be\u2026","rel":"","context":"In &quot;IBM&quot;","block_context":{"text":"IBM","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/ibm-work-et-al\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4046,"url":"https:\/\/www.flamingspork.com\/blog\/2016\/04\/29\/openpower-opencompute-and-fostering-a-firmware-development-community\/","url_meta":{"origin":4419,"position":3},"title":"OpenPOWER, OpenCompute and fostering a firmware development community","author":"Stewart Smith","date":"2016-04-29","format":false,"excerpt":"Recently, I was at the OpenPOWER Summit in San Jose where people could see the Barreleye server (specs and design here, initial Rackspace blog post here). Barreleye is an OpenCompute form factor POWER8 server. It's not only an OpenPOWER machine, which means all of the host firmware is free and\u2026","rel":"","context":"In &quot;IBM&quot;","block_context":{"text":"IBM","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/ibm-work-et-al\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4561,"url":"https:\/\/www.flamingspork.com\/blog\/2020\/03\/08\/yet-another-near-upstream-raptor-blackbird-firmware-build\/","url_meta":{"origin":4419,"position":4},"title":"Yet another near-upstream Raptor Blackbird firmware build","author":"Stewart Smith","date":"2020-03-08","format":false,"excerpt":"In what is coming a month occurance, I've put up yet another firmware build for the Raptor Blackbird with close-to-upstream firmware (see here and here for previous ones). Well, I\u00e2\u20ac\u2122ve done another build! It\u00e2\u20ac\u2122s current op-build (as of yesterday), but my branch with patches for the Raptor Blackbird. The skiboot\u2026","rel":"","context":"In &quot;General&quot;","block_context":{"text":"General","link":"https:\/\/www.flamingspork.com\/blog\/category\/general\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4495,"url":"https:\/\/www.flamingspork.com\/blog\/2019\/12\/10\/blackbird-singing-in-the-dead-of-night\/","url_meta":{"origin":4419,"position":5},"title":"Blackbird (singing in the dead of night..)","author":"Stewart Smith","date":"2019-12-10","format":false,"excerpt":"Way back when Raptor Computer Systems was doing pre-orders for the microATX Blackboard POWER9 system, I put in a pre-order. Since then, I've had a few life changes (such as moving to the US and starting to work for Amazon rather than IBM), but I've finally gone and done (most\u2026","rel":"","context":"In &quot;cool gadgets&quot;","block_context":{"text":"cool gadgets","link":"https:\/\/www.flamingspork.com\/blog\/category\/cool-gadgets\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2019\/12\/IMG_4007-scaled.jpg?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2019\/12\/IMG_4007-scaled.jpg?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2019\/12\/IMG_4007-scaled.jpg?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2019\/12\/IMG_4007-scaled.jpg?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2019\/12\/IMG_4007-scaled.jpg?resize=1050%2C600 3x, https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2019\/12\/IMG_4007-scaled.jpg?resize=1400%2C800 4x"},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/4419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/comments?post=4419"}],"version-history":[{"count":1,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/4419\/revisions"}],"predecessor-version":[{"id":4424,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/4419\/revisions\/4424"}],"wp:attachment":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/media?parent=4419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/categories?post=4419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/tags?post=4419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}