update_engine_client: add O_DSYNC flags

Out-Of-Memory (OOM) kernel crash reports spike about 2x when new
releases are pushed to Jetstream devices: "Google Wifi" only has
512MB total ram and only about 370MB available for all of user space
tasks (AP deamons, update engine, crash reporting, etc). About half of
the OOM reports show "active_anon" was > 350MB though "dirty" was
generally very low (< 10MB) in those same OOM reports.

While "cros flash $IP" is running (uses update_engine_client), "dirty"
would climb to ~100MB (on gale; ~200MB for whirlwind) for most of the
duration that the update was being written.  Those pages are no longer
available for general use. However, "cros flash" by default is performing
a "full update" and not a delta update which is what users typically get.
The difference is where the data is sourced from: a "delta update" is a
combination of "patch updates" and the currently in-use partition while
"full update" means the entire image comes over the network (compressed).
In both cases, the entire new KERNEL and ROOT partition are rewritten.

Adding two flags to open() call can improve this situation:

O_DSYNC will guarantee the write() syscall does not return until
the data has (a) landed on the device and (b) flushed from the
device cache (uses SCSI FUA). This limits the number of dirty
pages occupying host RAM.

O_DIRECT will bypass the buffer cache and write directly from host
memory. However, until the write() calls are block size and block
aligned offsets, we can't turn this on. So current behavior will
still "pollute" the buffer cache but at least the pages of mem
can be recycled for other apps (due to O_DSYNC).

With this change, "dirty" was generally < 200KB on whirlwind (huge
improvement!) with two exceptions:
60 seconds after "Preparing update" (peak  ~70MB for < 5 seconds)
10 seconds after "Update completed" (peak ~220MB for about 30 seconds)

The first exception is scp getting the "delta" update from the host.

The second exception is running scp then "tar + gzip" - possibly
downloading and unpacking of /usr/local/autotest (et al) for "test" builds.

BUG=b:31709028
TEST=monitor buffer cache size while update_engine_client is running on gale.
    Verify "delta" usage is < 10MB peak with change.
    test_that $DUT_IP autoupdate_EndToEndTest

Change-Id: I993aa541cc29d818920312c0a900afaba9f88b74
Reviewed-on: https://chromium-review.googlesource.com/502369
Commit-Ready: Grant Grundler <grundler@chromium.org>
Tested-by: Grant Grundler <grundler@chromium.org>
Reviewed-by: Dan Erat <derat@chromium.org>
Reviewed-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Grant Grundler <grundler@chromium.org>
1 file changed
tree: 141253e03e3d220413646a33c9cb69a4e57c6a02
  1. binder_bindings/
  2. client_library/
  3. common/
  4. dbus_bindings/
  5. include/
  6. init/
  7. payload_consumer/
  8. payload_generator/
  9. sample_images/
  10. scripts/
  11. update_manager/
  12. update_payload_key/
  13. weaved/
  14. .gitignore
  15. Android.mk
  16. binder_service_android.cc
  17. binder_service_android.h
  18. binder_service_brillo.cc
  19. binder_service_brillo.h
  20. boot_control_android.cc
  21. boot_control_android.h
  22. boot_control_chromeos.cc
  23. boot_control_chromeos.h
  24. boot_control_chromeos_unittest.cc
  25. chrome_browser_proxy_resolver.cc
  26. chrome_browser_proxy_resolver.h
  27. chrome_browser_proxy_resolver_unittest.cc
  28. common_service.cc
  29. common_service.h
  30. common_service_unittest.cc
  31. connection_manager.cc
  32. connection_manager.h
  33. connection_manager_interface.h
  34. connection_manager_unittest.cc
  35. daemon.cc
  36. daemon.h
  37. daemon_state_android.cc
  38. daemon_state_android.h
  39. daemon_state_interface.h
  40. dbus_service.cc
  41. dbus_service.h
  42. dbus_test_utils.h
  43. fake_file_writer.h
  44. fake_p2p_manager.h
  45. fake_p2p_manager_configuration.h
  46. fake_shill_proxy.cc
  47. fake_shill_proxy.h
  48. fake_system_state.cc
  49. fake_system_state.h
  50. generate_pc_file.sh
  51. hardware_android.cc
  52. hardware_android.h
  53. hardware_chromeos.cc
  54. hardware_chromeos.h
  55. hardware_chromeos_unittest.cc
  56. image_properties.h
  57. image_properties_android.cc
  58. image_properties_chromeos.cc
  59. image_properties_chromeos_unittest.cc
  60. libupdate_engine-client-test.pc.in
  61. libupdate_engine-client.pc.in
  62. local_coverage_rate
  63. main.cc
  64. metrics.cc
  65. metrics.h
  66. metrics_utils.cc
  67. metrics_utils.h
  68. metrics_utils_unittest.cc
  69. mock_connection_manager.h
  70. mock_file_writer.h
  71. mock_omaha_request_params.h
  72. mock_p2p_manager.h
  73. mock_payload_state.h
  74. mock_proxy_resolver.h
  75. mock_update_attempter.h
  76. MODULE_LICENSE_APACHE2
  77. NOTICE
  78. omaha_request_action.cc
  79. omaha_request_action.h
  80. omaha_request_action_unittest.cc
  81. omaha_request_params.cc
  82. omaha_request_params.h
  83. omaha_request_params_unittest.cc
  84. omaha_response.h
  85. omaha_response_handler_action.cc
  86. omaha_response_handler_action.h
  87. omaha_response_handler_action_unittest.cc
  88. omaha_utils.cc
  89. omaha_utils.h
  90. omaha_utils_unittest.cc
  91. OWNERS
  92. p2p_manager.cc
  93. p2p_manager.h
  94. p2p_manager_unittest.cc
  95. parcelable_update_engine_status.cc
  96. parcelable_update_engine_status.h
  97. payload_state.cc
  98. payload_state.h
  99. payload_state_interface.h
  100. payload_state_unittest.cc
  101. PRESUBMIT.cfg
  102. proxy_resolver.cc
  103. proxy_resolver.h
  104. proxy_resolver_unittest.cc
  105. real_system_state.cc
  106. real_system_state.h
  107. run_unittests
  108. sample_omaha_v3_response.xml
  109. service_delegate_android_interface.h
  110. service_observer_interface.h
  111. shill_proxy.cc
  112. shill_proxy.h
  113. shill_proxy_interface.h
  114. system_state.h
  115. tar_bunzip2.gypi
  116. test_http_server.cc
  117. test_subprocess.cc
  118. testrunner.cc
  119. unittest_key.pem
  120. unittest_key2.pem
  121. update_attempter.cc
  122. update_attempter.h
  123. update_attempter_android.cc
  124. update_attempter_android.h
  125. update_attempter_unittest.cc
  126. update_engine-client.gyp
  127. update_engine.conf
  128. update_engine.gyp
  129. update_engine.rc
  130. update_engine_client.cc
  131. update_engine_client_android.cc
  132. update_metadata.proto
  133. update_status_utils.cc
  134. update_status_utils.h
  135. UpdateEngine.conf
  136. WATCHLISTS
  137. weave_service.cc
  138. weave_service.h
  139. weave_service_factory.cc
  140. weave_service_factory.h
  141. weave_service_interface.h