Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52f1c19a authored by Akilesh Kailash's avatar Akilesh Kailash
Browse files

Allow direct reads on source device



Allow O_DIRECT reads on source block device.
This will further cut down the Active and Inactive file pages
during partition verification.

On Pixel 6 after incremental OTA - Post OTA reboot:

		Without patch      With patch     Delta
--------------------------------------------------------
Inactive(File):  4992MB             3887MB         ~22%
Active(File):    1465MB             1014MB         ~30%

Boot time however increases from 25 to 30 seconds.

This is not yet enabled. This will be behind a sysprop flag
or for low memory devices and will be enabled later.

Additionally, set the priority of worker threads to normal.
Merge threads priority is reduced. This will help low memory
devices as tested on Pixel watch.

Bug: 311233916
Test: OTA on Pixel 6
Change-Id: Icacdef08d68e28d3062611477703e7cf393a9f10
Signed-off-by: default avatarAkilesh Kailash <akailash@google.com>
parent a8f6ce33
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ Extractor::Extractor(const std::string& base_path, const std::string& cow_path)
bool Extractor::Init() {
    auto opener = factory_.CreateTestOpener(control_name_);
    handler_ = std::make_shared<SnapshotHandler>(control_name_, cow_path_, base_path_, base_path_,
                                                 opener, 1, false, false);
                                                 opener, 1, false, false, false);
    if (!handler_->InitCowDevice()) {
        return false;
    }
@@ -50,7 +50,7 @@ bool Extractor::Init() {
    }

    read_worker_ = std::make_unique<ReadWorker>(cow_path_, base_path_, control_name_, base_path_,
                                                handler_->GetSharedPtr(), opener);
                                                handler_->GetSharedPtr(), opener, false);
    if (!read_worker_->Init()) {
        return false;
    }
+5 −4
Original line number Diff line number Diff line
@@ -51,10 +51,11 @@ SnapshotHandlerManager::SnapshotHandlerManager() {
std::shared_ptr<HandlerThread> SnapshotHandlerManager::AddHandler(
        const std::string& misc_name, const std::string& cow_device_path,
        const std::string& backing_device, const std::string& base_path_merge,
        std::shared_ptr<IBlockServerOpener> opener, int num_worker_threads, bool use_iouring) {
    auto snapuserd = std::make_shared<SnapshotHandler>(misc_name, cow_device_path, backing_device,
                                                       base_path_merge, opener, num_worker_threads,
                                                       use_iouring, perform_verification_);
        std::shared_ptr<IBlockServerOpener> opener, int num_worker_threads, bool use_iouring,
        bool o_direct) {
    auto snapuserd = std::make_shared<SnapshotHandler>(
            misc_name, cow_device_path, backing_device, base_path_merge, opener, num_worker_threads,
            use_iouring, perform_verification_, o_direct);
    if (!snapuserd->InitCowDevice()) {
        LOG(ERROR) << "Failed to initialize Snapuserd";
        return nullptr;
+4 −2
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ class ISnapshotHandlerManager {
                                                      const std::string& backing_device,
                                                      const std::string& base_path_merge,
                                                      std::shared_ptr<IBlockServerOpener> opener,
                                                      int num_worker_threads, bool use_iouring) = 0;
                                                      int num_worker_threads, bool use_iouring,
                                                      bool o_direct) = 0;

    // Start serving requests on a snapshot handler.
    virtual bool StartHandler(const std::string& misc_name) = 0;
@@ -96,7 +97,8 @@ class SnapshotHandlerManager final : public ISnapshotHandlerManager {
                                              const std::string& backing_device,
                                              const std::string& base_path_merge,
                                              std::shared_ptr<IBlockServerOpener> opener,
                                              int num_worker_threads, bool use_iouring) override;
                                              int num_worker_threads, bool use_iouring,
                                              bool o_direct) override;
    bool StartHandler(const std::string& misc_name) override;
    bool DeleteHandler(const std::string& misc_name) override;
    bool InitiateMerge(const std::string& misc_name) override;
+1 −1
Original line number Diff line number Diff line
@@ -557,7 +557,7 @@ bool MergeWorker::Run() {
        return true;
    }

    if (!SetThreadPriority(kNiceValueForMergeThreads)) {
    if (!SetThreadPriority(ANDROID_PRIORITY_BACKGROUND)) {
        SNAP_PLOG(ERROR) << "Failed to set thread priority";
    }

+35 −3
Original line number Diff line number Diff line
@@ -31,16 +31,19 @@ using android::base::unique_fd;
void ReadWorker::CloseFds() {
    block_server_ = {};
    backing_store_fd_ = {};
    backing_store_direct_fd_ = {};
    Worker::CloseFds();
}

ReadWorker::ReadWorker(const std::string& cow_device, const std::string& backing_device,
                       const std::string& misc_name, const std::string& base_path_merge,
                       std::shared_ptr<SnapshotHandler> snapuserd,
                       std::shared_ptr<IBlockServerOpener> opener)
                       std::shared_ptr<IBlockServerOpener> opener, bool direct_read)
    : Worker(cow_device, misc_name, base_path_merge, snapuserd),
      backing_store_device_(backing_device),
      block_server_opener_(opener) {}
      direct_read_(direct_read),
      block_server_opener_(opener),
      aligned_buffer_(std::unique_ptr<void, decltype(&::free)>(nullptr, &::free)) {}

// Start the replace operation. This will read the
// internal COW format and if the block is compressed,
@@ -61,6 +64,17 @@ bool ReadWorker::ReadFromSourceDevice(const CowOperation* cow_op, void* buffer)
    }
    SNAP_LOG(DEBUG) << " ReadFromBaseDevice...: new-block: " << cow_op->new_block
                    << " Op: " << *cow_op;

    if (direct_read_ && IsBlockAligned(offset)) {
        if (!android::base::ReadFullyAtOffset(backing_store_direct_fd_, aligned_buffer_.get(),
                                              BLOCK_SZ, offset)) {
            SNAP_PLOG(ERROR) << "O_DIRECT Read failed at offset: " << offset;
            return false;
        }
        std::memcpy(buffer, aligned_buffer_.get(), BLOCK_SZ);
        return true;
    }

    if (!android::base::ReadFullyAtOffset(backing_store_fd_, buffer, BLOCK_SZ, offset)) {
        std::string op;
        if (cow_op->type() == kCowCopyOp)
@@ -201,6 +215,24 @@ bool ReadWorker::Init() {
        return false;
    }

    if (direct_read_) {
        backing_store_direct_fd_.reset(open(backing_store_device_.c_str(), O_RDONLY | O_DIRECT));
        if (backing_store_direct_fd_ < 0) {
            SNAP_PLOG(ERROR) << "Open Failed with O_DIRECT: " << backing_store_direct_fd_;
            direct_read_ = false;
        } else {
            void* aligned_addr;
            ssize_t page_size = getpagesize();
            if (posix_memalign(&aligned_addr, page_size, page_size) < 0) {
                direct_read_ = false;
                SNAP_PLOG(ERROR) << "posix_memalign failed "
                                 << " page_size: " << page_size << " read_sz: " << page_size;
            } else {
                aligned_buffer_.reset(aligned_addr);
            }
        }
    }

    block_server_ = block_server_opener_->Open(this, PAYLOAD_BUFFER_SZ);
    if (!block_server_) {
        SNAP_PLOG(ERROR) << "Unable to open block server";
@@ -214,7 +246,7 @@ bool ReadWorker::Run() {

    pthread_setname_np(pthread_self(), "ReadWorker");

    if (!SetThreadPriority(kNiceValueForMergeThreads)) {
    if (!SetThreadPriority(ANDROID_PRIORITY_NORMAL)) {
        SNAP_PLOG(ERROR) << "Failed to set thread priority";
    }

Loading