Loading adb/benchmark_device.py +39 −0 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,8 @@ import os import os import statistics import statistics import subprocess import tempfile import time import time import adb import adb Loading Loading @@ -56,6 +58,41 @@ def analyze(name, speeds): msg = "%s: %d runs: median %.2f MiB/s, mean %.2f MiB/s, stddev: %.2f MiB/s" msg = "%s: %d runs: median %.2f MiB/s, mean %.2f MiB/s, stddev: %.2f MiB/s" print(msg % (name, len(speeds), median, mean, stddev)) print(msg % (name, len(speeds), median, mean, stddev)) def benchmark_sink(device=None, size_mb=100): if device == None: device = adb.get_device() speeds = list() cmd = device.adb_cmd + ["raw", "sink:%d" % (size_mb * 1024 * 1024)] with tempfile.TemporaryFile() as tmpfile: tmpfile.truncate(size_mb * 1024 * 1024) for _ in range(0, 10): tmpfile.seek(0) begin = time.time() subprocess.check_call(cmd, stdin=tmpfile) end = time.time() speeds.append(size_mb / float(end - begin)) analyze("sink %dMiB" % size_mb, speeds) def benchmark_source(device=None, size_mb=100): if device == None: device = adb.get_device() speeds = list() cmd = device.adb_cmd + ["raw", "source:%d" % (size_mb * 1024 * 1024)] with open(os.devnull, 'w') as devnull: for _ in range(0, 10): begin = time.time() subprocess.check_call(cmd, stdout=devnull) end = time.time() speeds.append(size_mb / float(end - begin)) analyze("source %dMiB" % size_mb, speeds) def benchmark_push(device=None, file_size_mb=100): def benchmark_push(device=None, file_size_mb=100): if device == None: if device == None: device = adb.get_device() device = adb.get_device() Loading Loading @@ -110,6 +147,8 @@ def benchmark_shell(device=None, file_size_mb=100): def main(): def main(): device = adb.get_device() device = adb.get_device() unlock(device) unlock(device) benchmark_sink(device) benchmark_source(device) benchmark_push(device) benchmark_push(device) benchmark_pull(device) benchmark_pull(device) Loading adb/daemon/usb.cpp +67 −41 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <linux/usb/functionfs.h> #include <linux/usb/functionfs.h> #include <sys/eventfd.h> #include <sys/eventfd.h> #include <algorithm> #include <array> #include <array> #include <future> #include <future> #include <memory> #include <memory> Loading Loading @@ -56,10 +57,11 @@ using android::base::StringPrintf; // We can't find out whether we have support for AIO on ffs endpoints until we submit a read. // We can't find out whether we have support for AIO on ffs endpoints until we submit a read. static std::optional<bool> gFfsAioSupported; static std::optional<bool> gFfsAioSupported; static constexpr size_t kUsbReadQueueDepth = 16; static constexpr size_t kUsbReadQueueDepth = 32; static constexpr size_t kUsbReadSize = 16384; static constexpr size_t kUsbReadSize = 8 * PAGE_SIZE; static constexpr size_t kUsbWriteQueueDepth = 16; static constexpr size_t kUsbWriteQueueDepth = 32; static constexpr size_t kUsbWriteSize = 8 * PAGE_SIZE; static const char* to_string(enum usb_functionfs_event_type type) { static const char* to_string(enum usb_functionfs_event_type type) { switch (type) { switch (type) { Loading Loading @@ -115,7 +117,7 @@ struct TransferId { struct IoBlock { struct IoBlock { bool pending; bool pending; struct iocb control; struct iocb control; Block payload; std::shared_ptr<Block> payload; TransferId id() const { return TransferId::from_value(control.aio_data); } TransferId id() const { return TransferId::from_value(control.aio_data); } }; }; Loading Loading @@ -207,8 +209,20 @@ struct UsbFfsConnection : public Connection { std::lock_guard<std::mutex> lock(write_mutex_); std::lock_guard<std::mutex> lock(write_mutex_); write_requests_.push_back(CreateWriteBlock(std::move(header), next_write_id_++)); write_requests_.push_back(CreateWriteBlock(std::move(header), next_write_id_++)); if (!packet->payload.empty()) { if (!packet->payload.empty()) { // The kernel attempts to allocate a contiguous block of memory for each write, // which can fail if the write is large and the kernel heap is fragmented. // Split large writes into smaller chunks to avoid this. std::shared_ptr<Block> payload = std::make_shared<Block>(std::move(packet->payload)); size_t offset = 0; size_t len = payload->size(); while (len > 0) { size_t write_size = std::min(kUsbWriteSize, len); write_requests_.push_back( write_requests_.push_back( CreateWriteBlock(std::move(packet->payload), next_write_id_++)); CreateWriteBlock(payload, offset, write_size, next_write_id_++)); len -= write_size; offset += write_size; } } } SubmitWrites(); SubmitWrites(); return true; return true; Loading Loading @@ -246,7 +260,6 @@ struct UsbFfsConnection : public Connection { // until it dies, and then report failure to the transport via HandleError, which will // until it dies, and then report failure to the transport via HandleError, which will // eventually result in the transport being destroyed, which will result in UsbFfsConnection // eventually result in the transport being destroyed, which will result in UsbFfsConnection // being destroyed, which unblocks the open thread and restarts this entire process. // being destroyed, which unblocks the open thread and restarts this entire process. static constexpr int kInterruptionSignal = SIGUSR1; static std::once_flag handler_once; static std::once_flag handler_once; std::call_once(handler_once, []() { signal(kInterruptionSignal, [](int) {}); }); std::call_once(handler_once, []() { signal(kInterruptionSignal, [](int) {}); }); Loading @@ -272,6 +285,7 @@ struct UsbFfsConnection : public Connection { } else if (rc == 0) { } else if (rc == 0) { // Something in the kernel presumably went wrong. // Something in the kernel presumably went wrong. // Close our endpoints, wait for a bit, and then try again. // Close our endpoints, wait for a bit, and then try again. StopWorker(); aio_context_.reset(); aio_context_.reset(); read_fd_.reset(); read_fd_.reset(); write_fd_.reset(); write_fd_.reset(); Loading @@ -297,7 +311,7 @@ struct UsbFfsConnection : public Connection { switch (event.type) { switch (event.type) { case FUNCTIONFS_BIND: case FUNCTIONFS_BIND: CHECK(!started) << "received FUNCTIONFS_ENABLE while already bound?"; CHECK(!bound) << "received FUNCTIONFS_BIND while already bound?"; bound = true; bound = true; break; break; Loading @@ -313,28 +327,7 @@ struct UsbFfsConnection : public Connection { } } } } pthread_t worker_thread_handle = worker_thread_.native_handle(); StopWorker(); while (true) { int rc = pthread_kill(worker_thread_handle, kInterruptionSignal); if (rc != 0) { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); break; } std::this_thread::sleep_for(100ms); rc = pthread_kill(worker_thread_handle, 0); if (rc == 0) { continue; } else if (rc == ESRCH) { break; } else { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); } } worker_thread_.join(); aio_context_.reset(); aio_context_.reset(); read_fd_.reset(); read_fd_.reset(); write_fd_.reset(); write_fd_.reset(); Loading Loading @@ -365,12 +358,36 @@ struct UsbFfsConnection : public Connection { }); }); } } void StopWorker() { pthread_t worker_thread_handle = worker_thread_.native_handle(); while (true) { int rc = pthread_kill(worker_thread_handle, kInterruptionSignal); if (rc != 0) { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); break; } std::this_thread::sleep_for(100ms); rc = pthread_kill(worker_thread_handle, 0); if (rc == 0) { continue; } else if (rc == ESRCH) { break; } else { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); } } worker_thread_.join(); } void PrepareReadBlock(IoBlock* block, uint64_t id) { void PrepareReadBlock(IoBlock* block, uint64_t id) { block->pending = false; block->pending = false; block->payload.resize(kUsbReadSize); block->payload = std::make_shared<Block>(kUsbReadSize); block->control.aio_data = static_cast<uint64_t>(TransferId::read(id)); block->control.aio_data = static_cast<uint64_t>(TransferId::read(id)); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload.data()); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload->data()); block->control.aio_nbytes = block->payload.size(); block->control.aio_nbytes = block->payload->size(); } } IoBlock CreateReadBlock(uint64_t id) { IoBlock CreateReadBlock(uint64_t id) { Loading Loading @@ -421,7 +438,7 @@ struct UsbFfsConnection : public Connection { uint64_t read_idx = id.id % kUsbReadQueueDepth; uint64_t read_idx = id.id % kUsbReadQueueDepth; IoBlock* block = &read_requests_[read_idx]; IoBlock* block = &read_requests_[read_idx]; block->pending = false; block->pending = false; block->payload.resize(size); block->payload->resize(size); // Notification for completed reads can be received out of order. // Notification for completed reads can be received out of order. if (block->id().id != needed_read_id_) { if (block->id().id != needed_read_id_) { Loading @@ -442,16 +459,16 @@ struct UsbFfsConnection : public Connection { } } void ProcessRead(IoBlock* block) { void ProcessRead(IoBlock* block) { if (!block->payload.empty()) { if (!block->payload->empty()) { if (!incoming_header_.has_value()) { if (!incoming_header_.has_value()) { CHECK_EQ(sizeof(amessage), block->payload.size()); CHECK_EQ(sizeof(amessage), block->payload->size()); amessage msg; amessage msg; memcpy(&msg, block->payload.data(), sizeof(amessage)); memcpy(&msg, block->payload->data(), sizeof(amessage)); LOG(DEBUG) << "USB read:" << dump_header(&msg); LOG(DEBUG) << "USB read:" << dump_header(&msg); incoming_header_ = msg; incoming_header_ = msg; } else { } else { size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); Block payload = std::move(block->payload); Block payload = std::move(*block->payload); CHECK_LE(payload.size(), bytes_left); CHECK_LE(payload.size(), bytes_left); incoming_payload_.append(std::make_unique<Block>(std::move(payload))); incoming_payload_.append(std::make_unique<Block>(std::move(payload))); } } Loading Loading @@ -506,7 +523,8 @@ struct UsbFfsConnection : public Connection { SubmitWrites(); SubmitWrites(); } } std::unique_ptr<IoBlock> CreateWriteBlock(Block payload, uint64_t id) { std::unique_ptr<IoBlock> CreateWriteBlock(std::shared_ptr<Block> payload, size_t offset, size_t len, uint64_t id) { auto block = std::make_unique<IoBlock>(); auto block = std::make_unique<IoBlock>(); block->payload = std::move(payload); block->payload = std::move(payload); block->control.aio_data = static_cast<uint64_t>(TransferId::write(id)); block->control.aio_data = static_cast<uint64_t>(TransferId::write(id)); Loading @@ -514,14 +532,20 @@ struct UsbFfsConnection : public Connection { block->control.aio_lio_opcode = IOCB_CMD_PWRITE; block->control.aio_lio_opcode = IOCB_CMD_PWRITE; block->control.aio_reqprio = 0; block->control.aio_reqprio = 0; block->control.aio_fildes = write_fd_.get(); block->control.aio_fildes = write_fd_.get(); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload.data()); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload->data() + offset); block->control.aio_nbytes = block->payload.size(); block->control.aio_nbytes = len; block->control.aio_offset = 0; block->control.aio_offset = 0; block->control.aio_flags = IOCB_FLAG_RESFD; block->control.aio_flags = IOCB_FLAG_RESFD; block->control.aio_resfd = worker_event_fd_.get(); block->control.aio_resfd = worker_event_fd_.get(); return block; return block; } } std::unique_ptr<IoBlock> CreateWriteBlock(Block payload, uint64_t id) { std::shared_ptr<Block> block = std::make_shared<Block>(std::move(payload)); size_t len = block->size(); return CreateWriteBlock(std::move(block), 0, len, id); } void SubmitWrites() REQUIRES(write_mutex_) { void SubmitWrites() REQUIRES(write_mutex_) { if (writes_submitted_ == kUsbWriteQueueDepth) { if (writes_submitted_ == kUsbWriteQueueDepth) { return; return; Loading Loading @@ -594,6 +618,8 @@ struct UsbFfsConnection : public Connection { std::deque<std::unique_ptr<IoBlock>> write_requests_ GUARDED_BY(write_mutex_); std::deque<std::unique_ptr<IoBlock>> write_requests_ GUARDED_BY(write_mutex_); size_t next_write_id_ GUARDED_BY(write_mutex_) = 0; size_t next_write_id_ GUARDED_BY(write_mutex_) = 0; size_t writes_submitted_ GUARDED_BY(write_mutex_) = 0; size_t writes_submitted_ GUARDED_BY(write_mutex_) = 0; static constexpr int kInterruptionSignal = SIGUSR1; }; }; void usb_init_legacy(); void usb_init_legacy(); Loading bootstat/OWNERS +1 −0 Original line number Original line Diff line number Diff line jhawkins@google.com jhawkins@google.com salyzyn@google.com fastboot/fastboot_driver.cpp +7 −2 Original line number Original line Diff line number Diff line Loading @@ -403,7 +403,7 @@ RetCode FastBootDriver::DownloadCommand(uint32_t size, std::string* response, RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::string>* info, RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::string>* info, int* dsize) { int* dsize) { char status[FB_RESPONSE_SZ + 1]; char status[FB_RESPONSE_SZ + 1]; auto start = std::chrono::system_clock::now(); auto start = std::chrono::steady_clock::now(); auto set_response = [response](std::string s) { auto set_response = [response](std::string s) { if (response) *response = std::move(s); if (response) *response = std::move(s); Loading @@ -414,7 +414,7 @@ RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::s // erase response // erase response set_response(""); set_response(""); while ((std::chrono::system_clock::now() - start) < std::chrono::seconds(RESP_TIMEOUT)) { while ((std::chrono::steady_clock::now() - start) < std::chrono::seconds(RESP_TIMEOUT)) { int r = transport_->Read(status, FB_RESPONSE_SZ); int r = transport_->Read(status, FB_RESPONSE_SZ); if (r < 0) { if (r < 0) { error_ = ErrnoStr("Status read failed"); error_ = ErrnoStr("Status read failed"); Loading @@ -427,6 +427,11 @@ RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::s std::string tmp = input.substr(strlen("INFO")); std::string tmp = input.substr(strlen("INFO")); info_(tmp); info_(tmp); add_info(std::move(tmp)); add_info(std::move(tmp)); // We may receive one or more INFO packets during long operations, // e.g. flash/erase if they are back by slow media like NAND/NOR // flash. In that case, reset the timer since it's not a real // timeout. start = std::chrono::steady_clock::now(); } else if (android::base::StartsWith(input, "OKAY")) { } else if (android::base::StartsWith(input, "OKAY")) { set_response(input.substr(strlen("OKAY"))); set_response(input.substr(strlen("OKAY"))); return SUCCESS; return SUCCESS; Loading fs_mgr/fs_mgr_fstab.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -307,6 +307,8 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } else { } else { entry->logical_blk_size = val; entry->logical_blk_size = val; } } } else if (StartsWith(flag, "avb_keys=")) { // must before the following "avb" entry->avb_keys = arg; } else if (StartsWith(flag, "avb")) { } else if (StartsWith(flag, "avb")) { entry->fs_mgr_flags.avb = true; entry->fs_mgr_flags.avb = true; entry->vbmeta_partition = arg; entry->vbmeta_partition = arg; Loading @@ -325,8 +327,6 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } } } else if (StartsWith(flag, "zram_backing_dev_path=")) { } else if (StartsWith(flag, "zram_backing_dev_path=")) { entry->zram_backing_dev_path = arg; entry->zram_backing_dev_path = arg; } else if (StartsWith(flag, "avb_keys=")) { entry->avb_keys = arg; } else { } else { LWARNING << "Warning: unknown flag: " << flag; LWARNING << "Warning: unknown flag: " << flag; } } Loading Loading
adb/benchmark_device.py +39 −0 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,8 @@ import os import os import statistics import statistics import subprocess import tempfile import time import time import adb import adb Loading Loading @@ -56,6 +58,41 @@ def analyze(name, speeds): msg = "%s: %d runs: median %.2f MiB/s, mean %.2f MiB/s, stddev: %.2f MiB/s" msg = "%s: %d runs: median %.2f MiB/s, mean %.2f MiB/s, stddev: %.2f MiB/s" print(msg % (name, len(speeds), median, mean, stddev)) print(msg % (name, len(speeds), median, mean, stddev)) def benchmark_sink(device=None, size_mb=100): if device == None: device = adb.get_device() speeds = list() cmd = device.adb_cmd + ["raw", "sink:%d" % (size_mb * 1024 * 1024)] with tempfile.TemporaryFile() as tmpfile: tmpfile.truncate(size_mb * 1024 * 1024) for _ in range(0, 10): tmpfile.seek(0) begin = time.time() subprocess.check_call(cmd, stdin=tmpfile) end = time.time() speeds.append(size_mb / float(end - begin)) analyze("sink %dMiB" % size_mb, speeds) def benchmark_source(device=None, size_mb=100): if device == None: device = adb.get_device() speeds = list() cmd = device.adb_cmd + ["raw", "source:%d" % (size_mb * 1024 * 1024)] with open(os.devnull, 'w') as devnull: for _ in range(0, 10): begin = time.time() subprocess.check_call(cmd, stdout=devnull) end = time.time() speeds.append(size_mb / float(end - begin)) analyze("source %dMiB" % size_mb, speeds) def benchmark_push(device=None, file_size_mb=100): def benchmark_push(device=None, file_size_mb=100): if device == None: if device == None: device = adb.get_device() device = adb.get_device() Loading Loading @@ -110,6 +147,8 @@ def benchmark_shell(device=None, file_size_mb=100): def main(): def main(): device = adb.get_device() device = adb.get_device() unlock(device) unlock(device) benchmark_sink(device) benchmark_source(device) benchmark_push(device) benchmark_push(device) benchmark_pull(device) benchmark_pull(device) Loading
adb/daemon/usb.cpp +67 −41 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <linux/usb/functionfs.h> #include <linux/usb/functionfs.h> #include <sys/eventfd.h> #include <sys/eventfd.h> #include <algorithm> #include <array> #include <array> #include <future> #include <future> #include <memory> #include <memory> Loading Loading @@ -56,10 +57,11 @@ using android::base::StringPrintf; // We can't find out whether we have support for AIO on ffs endpoints until we submit a read. // We can't find out whether we have support for AIO on ffs endpoints until we submit a read. static std::optional<bool> gFfsAioSupported; static std::optional<bool> gFfsAioSupported; static constexpr size_t kUsbReadQueueDepth = 16; static constexpr size_t kUsbReadQueueDepth = 32; static constexpr size_t kUsbReadSize = 16384; static constexpr size_t kUsbReadSize = 8 * PAGE_SIZE; static constexpr size_t kUsbWriteQueueDepth = 16; static constexpr size_t kUsbWriteQueueDepth = 32; static constexpr size_t kUsbWriteSize = 8 * PAGE_SIZE; static const char* to_string(enum usb_functionfs_event_type type) { static const char* to_string(enum usb_functionfs_event_type type) { switch (type) { switch (type) { Loading Loading @@ -115,7 +117,7 @@ struct TransferId { struct IoBlock { struct IoBlock { bool pending; bool pending; struct iocb control; struct iocb control; Block payload; std::shared_ptr<Block> payload; TransferId id() const { return TransferId::from_value(control.aio_data); } TransferId id() const { return TransferId::from_value(control.aio_data); } }; }; Loading Loading @@ -207,8 +209,20 @@ struct UsbFfsConnection : public Connection { std::lock_guard<std::mutex> lock(write_mutex_); std::lock_guard<std::mutex> lock(write_mutex_); write_requests_.push_back(CreateWriteBlock(std::move(header), next_write_id_++)); write_requests_.push_back(CreateWriteBlock(std::move(header), next_write_id_++)); if (!packet->payload.empty()) { if (!packet->payload.empty()) { // The kernel attempts to allocate a contiguous block of memory for each write, // which can fail if the write is large and the kernel heap is fragmented. // Split large writes into smaller chunks to avoid this. std::shared_ptr<Block> payload = std::make_shared<Block>(std::move(packet->payload)); size_t offset = 0; size_t len = payload->size(); while (len > 0) { size_t write_size = std::min(kUsbWriteSize, len); write_requests_.push_back( write_requests_.push_back( CreateWriteBlock(std::move(packet->payload), next_write_id_++)); CreateWriteBlock(payload, offset, write_size, next_write_id_++)); len -= write_size; offset += write_size; } } } SubmitWrites(); SubmitWrites(); return true; return true; Loading Loading @@ -246,7 +260,6 @@ struct UsbFfsConnection : public Connection { // until it dies, and then report failure to the transport via HandleError, which will // until it dies, and then report failure to the transport via HandleError, which will // eventually result in the transport being destroyed, which will result in UsbFfsConnection // eventually result in the transport being destroyed, which will result in UsbFfsConnection // being destroyed, which unblocks the open thread and restarts this entire process. // being destroyed, which unblocks the open thread and restarts this entire process. static constexpr int kInterruptionSignal = SIGUSR1; static std::once_flag handler_once; static std::once_flag handler_once; std::call_once(handler_once, []() { signal(kInterruptionSignal, [](int) {}); }); std::call_once(handler_once, []() { signal(kInterruptionSignal, [](int) {}); }); Loading @@ -272,6 +285,7 @@ struct UsbFfsConnection : public Connection { } else if (rc == 0) { } else if (rc == 0) { // Something in the kernel presumably went wrong. // Something in the kernel presumably went wrong. // Close our endpoints, wait for a bit, and then try again. // Close our endpoints, wait for a bit, and then try again. StopWorker(); aio_context_.reset(); aio_context_.reset(); read_fd_.reset(); read_fd_.reset(); write_fd_.reset(); write_fd_.reset(); Loading @@ -297,7 +311,7 @@ struct UsbFfsConnection : public Connection { switch (event.type) { switch (event.type) { case FUNCTIONFS_BIND: case FUNCTIONFS_BIND: CHECK(!started) << "received FUNCTIONFS_ENABLE while already bound?"; CHECK(!bound) << "received FUNCTIONFS_BIND while already bound?"; bound = true; bound = true; break; break; Loading @@ -313,28 +327,7 @@ struct UsbFfsConnection : public Connection { } } } } pthread_t worker_thread_handle = worker_thread_.native_handle(); StopWorker(); while (true) { int rc = pthread_kill(worker_thread_handle, kInterruptionSignal); if (rc != 0) { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); break; } std::this_thread::sleep_for(100ms); rc = pthread_kill(worker_thread_handle, 0); if (rc == 0) { continue; } else if (rc == ESRCH) { break; } else { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); } } worker_thread_.join(); aio_context_.reset(); aio_context_.reset(); read_fd_.reset(); read_fd_.reset(); write_fd_.reset(); write_fd_.reset(); Loading Loading @@ -365,12 +358,36 @@ struct UsbFfsConnection : public Connection { }); }); } } void StopWorker() { pthread_t worker_thread_handle = worker_thread_.native_handle(); while (true) { int rc = pthread_kill(worker_thread_handle, kInterruptionSignal); if (rc != 0) { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); break; } std::this_thread::sleep_for(100ms); rc = pthread_kill(worker_thread_handle, 0); if (rc == 0) { continue; } else if (rc == ESRCH) { break; } else { LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc); } } worker_thread_.join(); } void PrepareReadBlock(IoBlock* block, uint64_t id) { void PrepareReadBlock(IoBlock* block, uint64_t id) { block->pending = false; block->pending = false; block->payload.resize(kUsbReadSize); block->payload = std::make_shared<Block>(kUsbReadSize); block->control.aio_data = static_cast<uint64_t>(TransferId::read(id)); block->control.aio_data = static_cast<uint64_t>(TransferId::read(id)); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload.data()); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload->data()); block->control.aio_nbytes = block->payload.size(); block->control.aio_nbytes = block->payload->size(); } } IoBlock CreateReadBlock(uint64_t id) { IoBlock CreateReadBlock(uint64_t id) { Loading Loading @@ -421,7 +438,7 @@ struct UsbFfsConnection : public Connection { uint64_t read_idx = id.id % kUsbReadQueueDepth; uint64_t read_idx = id.id % kUsbReadQueueDepth; IoBlock* block = &read_requests_[read_idx]; IoBlock* block = &read_requests_[read_idx]; block->pending = false; block->pending = false; block->payload.resize(size); block->payload->resize(size); // Notification for completed reads can be received out of order. // Notification for completed reads can be received out of order. if (block->id().id != needed_read_id_) { if (block->id().id != needed_read_id_) { Loading @@ -442,16 +459,16 @@ struct UsbFfsConnection : public Connection { } } void ProcessRead(IoBlock* block) { void ProcessRead(IoBlock* block) { if (!block->payload.empty()) { if (!block->payload->empty()) { if (!incoming_header_.has_value()) { if (!incoming_header_.has_value()) { CHECK_EQ(sizeof(amessage), block->payload.size()); CHECK_EQ(sizeof(amessage), block->payload->size()); amessage msg; amessage msg; memcpy(&msg, block->payload.data(), sizeof(amessage)); memcpy(&msg, block->payload->data(), sizeof(amessage)); LOG(DEBUG) << "USB read:" << dump_header(&msg); LOG(DEBUG) << "USB read:" << dump_header(&msg); incoming_header_ = msg; incoming_header_ = msg; } else { } else { size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); size_t bytes_left = incoming_header_->data_length - incoming_payload_.size(); Block payload = std::move(block->payload); Block payload = std::move(*block->payload); CHECK_LE(payload.size(), bytes_left); CHECK_LE(payload.size(), bytes_left); incoming_payload_.append(std::make_unique<Block>(std::move(payload))); incoming_payload_.append(std::make_unique<Block>(std::move(payload))); } } Loading Loading @@ -506,7 +523,8 @@ struct UsbFfsConnection : public Connection { SubmitWrites(); SubmitWrites(); } } std::unique_ptr<IoBlock> CreateWriteBlock(Block payload, uint64_t id) { std::unique_ptr<IoBlock> CreateWriteBlock(std::shared_ptr<Block> payload, size_t offset, size_t len, uint64_t id) { auto block = std::make_unique<IoBlock>(); auto block = std::make_unique<IoBlock>(); block->payload = std::move(payload); block->payload = std::move(payload); block->control.aio_data = static_cast<uint64_t>(TransferId::write(id)); block->control.aio_data = static_cast<uint64_t>(TransferId::write(id)); Loading @@ -514,14 +532,20 @@ struct UsbFfsConnection : public Connection { block->control.aio_lio_opcode = IOCB_CMD_PWRITE; block->control.aio_lio_opcode = IOCB_CMD_PWRITE; block->control.aio_reqprio = 0; block->control.aio_reqprio = 0; block->control.aio_fildes = write_fd_.get(); block->control.aio_fildes = write_fd_.get(); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload.data()); block->control.aio_buf = reinterpret_cast<uintptr_t>(block->payload->data() + offset); block->control.aio_nbytes = block->payload.size(); block->control.aio_nbytes = len; block->control.aio_offset = 0; block->control.aio_offset = 0; block->control.aio_flags = IOCB_FLAG_RESFD; block->control.aio_flags = IOCB_FLAG_RESFD; block->control.aio_resfd = worker_event_fd_.get(); block->control.aio_resfd = worker_event_fd_.get(); return block; return block; } } std::unique_ptr<IoBlock> CreateWriteBlock(Block payload, uint64_t id) { std::shared_ptr<Block> block = std::make_shared<Block>(std::move(payload)); size_t len = block->size(); return CreateWriteBlock(std::move(block), 0, len, id); } void SubmitWrites() REQUIRES(write_mutex_) { void SubmitWrites() REQUIRES(write_mutex_) { if (writes_submitted_ == kUsbWriteQueueDepth) { if (writes_submitted_ == kUsbWriteQueueDepth) { return; return; Loading Loading @@ -594,6 +618,8 @@ struct UsbFfsConnection : public Connection { std::deque<std::unique_ptr<IoBlock>> write_requests_ GUARDED_BY(write_mutex_); std::deque<std::unique_ptr<IoBlock>> write_requests_ GUARDED_BY(write_mutex_); size_t next_write_id_ GUARDED_BY(write_mutex_) = 0; size_t next_write_id_ GUARDED_BY(write_mutex_) = 0; size_t writes_submitted_ GUARDED_BY(write_mutex_) = 0; size_t writes_submitted_ GUARDED_BY(write_mutex_) = 0; static constexpr int kInterruptionSignal = SIGUSR1; }; }; void usb_init_legacy(); void usb_init_legacy(); Loading
bootstat/OWNERS +1 −0 Original line number Original line Diff line number Diff line jhawkins@google.com jhawkins@google.com salyzyn@google.com
fastboot/fastboot_driver.cpp +7 −2 Original line number Original line Diff line number Diff line Loading @@ -403,7 +403,7 @@ RetCode FastBootDriver::DownloadCommand(uint32_t size, std::string* response, RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::string>* info, RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::string>* info, int* dsize) { int* dsize) { char status[FB_RESPONSE_SZ + 1]; char status[FB_RESPONSE_SZ + 1]; auto start = std::chrono::system_clock::now(); auto start = std::chrono::steady_clock::now(); auto set_response = [response](std::string s) { auto set_response = [response](std::string s) { if (response) *response = std::move(s); if (response) *response = std::move(s); Loading @@ -414,7 +414,7 @@ RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::s // erase response // erase response set_response(""); set_response(""); while ((std::chrono::system_clock::now() - start) < std::chrono::seconds(RESP_TIMEOUT)) { while ((std::chrono::steady_clock::now() - start) < std::chrono::seconds(RESP_TIMEOUT)) { int r = transport_->Read(status, FB_RESPONSE_SZ); int r = transport_->Read(status, FB_RESPONSE_SZ); if (r < 0) { if (r < 0) { error_ = ErrnoStr("Status read failed"); error_ = ErrnoStr("Status read failed"); Loading @@ -427,6 +427,11 @@ RetCode FastBootDriver::HandleResponse(std::string* response, std::vector<std::s std::string tmp = input.substr(strlen("INFO")); std::string tmp = input.substr(strlen("INFO")); info_(tmp); info_(tmp); add_info(std::move(tmp)); add_info(std::move(tmp)); // We may receive one or more INFO packets during long operations, // e.g. flash/erase if they are back by slow media like NAND/NOR // flash. In that case, reset the timer since it's not a real // timeout. start = std::chrono::steady_clock::now(); } else if (android::base::StartsWith(input, "OKAY")) { } else if (android::base::StartsWith(input, "OKAY")) { set_response(input.substr(strlen("OKAY"))); set_response(input.substr(strlen("OKAY"))); return SUCCESS; return SUCCESS; Loading
fs_mgr/fs_mgr_fstab.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -307,6 +307,8 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } else { } else { entry->logical_blk_size = val; entry->logical_blk_size = val; } } } else if (StartsWith(flag, "avb_keys=")) { // must before the following "avb" entry->avb_keys = arg; } else if (StartsWith(flag, "avb")) { } else if (StartsWith(flag, "avb")) { entry->fs_mgr_flags.avb = true; entry->fs_mgr_flags.avb = true; entry->vbmeta_partition = arg; entry->vbmeta_partition = arg; Loading @@ -325,8 +327,6 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } } } else if (StartsWith(flag, "zram_backing_dev_path=")) { } else if (StartsWith(flag, "zram_backing_dev_path=")) { entry->zram_backing_dev_path = arg; entry->zram_backing_dev_path = arg; } else if (StartsWith(flag, "avb_keys=")) { entry->avb_keys = arg; } else { } else { LWARNING << "Warning: unknown flag: " << flag; LWARNING << "Warning: unknown flag: " << flag; } } Loading