Merge changes from topic 'adb_perf'
am: 42aa9a1415
Change-Id: I56b73a99b05634164379c700be9bdbd0a98c39c3
This commit is contained in:
commit
14e71a4af2
4 changed files with 54 additions and 15 deletions
|
|
@ -34,6 +34,8 @@ constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024;
|
||||||
constexpr size_t MAX_PAYLOAD_V2 = 256 * 1024;
|
constexpr size_t MAX_PAYLOAD_V2 = 256 * 1024;
|
||||||
constexpr size_t MAX_PAYLOAD = MAX_PAYLOAD_V2;
|
constexpr size_t MAX_PAYLOAD = MAX_PAYLOAD_V2;
|
||||||
|
|
||||||
|
constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304;
|
||||||
|
|
||||||
#define A_SYNC 0x434e5953
|
#define A_SYNC 0x434e5953
|
||||||
#define A_CNXN 0x4e584e43
|
#define A_CNXN 0x4e584e43
|
||||||
#define A_OPEN 0x4e45504f
|
#define A_OPEN 0x4e45504f
|
||||||
|
|
|
||||||
|
|
@ -49,16 +49,23 @@ using namespace std::chrono_literals;
|
||||||
#define MAX_PACKET_SIZE_HS 512
|
#define MAX_PACKET_SIZE_HS 512
|
||||||
#define MAX_PACKET_SIZE_SS 1024
|
#define MAX_PACKET_SIZE_SS 1024
|
||||||
|
|
||||||
// Writes larger than 16k fail on some devices (seed with 3.10.49-g209ea2f in particular).
|
// Kernels before 3.3 have a 16KiB transfer limit That limit was replaced
|
||||||
#define USB_FFS_MAX_WRITE 16384
|
// with a 16MiB global limit in 3.3, but each URB submitted required a
|
||||||
|
// contiguous kernel allocation, so you would get ENOMEM if you tried to
|
||||||
// The kernel allocates a contiguous buffer for reads, which can fail for large ones due to
|
// send something larger than the biggest available contiguous kernel
|
||||||
// fragmentation. 16k chosen arbitrarily to match the write limit.
|
// memory region. Large contiguous allocations could be unreliable
|
||||||
#define USB_FFS_MAX_READ 16384
|
// on a device kernel that has been running for a while fragmenting its
|
||||||
|
// memory so we start with a larger allocation, and shrink the amount if
|
||||||
|
// necessary.
|
||||||
|
#define USB_FFS_BULK_SIZE 16384
|
||||||
|
|
||||||
#define cpu_to_le16(x) htole16(x)
|
#define cpu_to_le16(x) htole16(x)
|
||||||
#define cpu_to_le32(x) htole32(x)
|
#define cpu_to_le32(x) htole32(x)
|
||||||
|
|
||||||
|
#define FUNCTIONFS_ENDPOINT_ALLOC _IOR('g', 231, __u32)
|
||||||
|
|
||||||
|
static constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;
|
||||||
|
|
||||||
static int dummy_fd = -1;
|
static int dummy_fd = -1;
|
||||||
|
|
||||||
struct func_desc {
|
struct func_desc {
|
||||||
|
|
@ -173,6 +180,7 @@ static struct ss_func_desc ss_descriptors = {
|
||||||
.source_comp = {
|
.source_comp = {
|
||||||
.bLength = sizeof(ss_descriptors.source_comp),
|
.bLength = sizeof(ss_descriptors.source_comp),
|
||||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||||
|
.bMaxBurst = 4,
|
||||||
},
|
},
|
||||||
.sink = {
|
.sink = {
|
||||||
.bLength = sizeof(ss_descriptors.sink),
|
.bLength = sizeof(ss_descriptors.sink),
|
||||||
|
|
@ -184,6 +192,7 @@ static struct ss_func_desc ss_descriptors = {
|
||||||
.sink_comp = {
|
.sink_comp = {
|
||||||
.bLength = sizeof(ss_descriptors.sink_comp),
|
.bLength = sizeof(ss_descriptors.sink_comp),
|
||||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||||
|
.bMaxBurst = 4,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -229,6 +238,7 @@ bool init_functionfs(struct usb_handle* h) {
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
struct desc_v1 v1_descriptor;
|
struct desc_v1 v1_descriptor;
|
||||||
struct desc_v2 v2_descriptor;
|
struct desc_v2 v2_descriptor;
|
||||||
|
size_t retries = 0;
|
||||||
|
|
||||||
v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
|
v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
|
||||||
v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
|
v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
|
||||||
|
|
@ -287,6 +297,29 @@ bool init_functionfs(struct usb_handle* h) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h->max_rw = MAX_PAYLOAD;
|
||||||
|
while (h->max_rw >= USB_FFS_BULK_SIZE && retries < ENDPOINT_ALLOC_RETRIES) {
|
||||||
|
int ret_in = ioctl(h->bulk_in, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(h->max_rw));
|
||||||
|
int errno_in = errno;
|
||||||
|
int ret_out = ioctl(h->bulk_out, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(h->max_rw));
|
||||||
|
int errno_out = errno;
|
||||||
|
|
||||||
|
if (ret_in || ret_out) {
|
||||||
|
if (errno_in == ENODEV || errno_out == ENODEV) {
|
||||||
|
std::this_thread::sleep_for(100ms);
|
||||||
|
retries += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
h->max_rw /= 2;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D("[ adb: cannot call endpoint alloc: errno=%d ]", errno);
|
||||||
|
// Kernel pre-allocation could have failed for recoverable reasons.
|
||||||
|
// Continue running with a safe max rw size.
|
||||||
|
h->max_rw *= 2;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
@ -340,7 +373,7 @@ static int usb_ffs_write(usb_handle* h, const void* data, int len) {
|
||||||
|
|
||||||
const char* buf = static_cast<const char*>(data);
|
const char* buf = static_cast<const char*>(data);
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
int write_len = std::min(USB_FFS_MAX_WRITE, len);
|
int write_len = std::min(h->max_rw, len);
|
||||||
int n = adb_write(h->bulk_in, buf, write_len);
|
int n = adb_write(h->bulk_in, buf, write_len);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
D("ERROR: fd = %d, n = %d: %s", h->bulk_in, n, strerror(errno));
|
D("ERROR: fd = %d, n = %d: %s", h->bulk_in, n, strerror(errno));
|
||||||
|
|
@ -359,7 +392,7 @@ static int usb_ffs_read(usb_handle* h, void* data, int len) {
|
||||||
|
|
||||||
char* buf = static_cast<char*>(data);
|
char* buf = static_cast<char*>(data);
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
int read_len = std::min(USB_FFS_MAX_READ, len);
|
int read_len = std::min(h->max_rw, len);
|
||||||
int n = adb_read(h->bulk_out, buf, read_len);
|
int n = adb_read(h->bulk_out, buf, read_len);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
D("ERROR: fd = %d, n = %d: %s", h->bulk_out, n, strerror(errno));
|
D("ERROR: fd = %d, n = %d: %s", h->bulk_out, n, strerror(errno));
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,6 @@
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
// Writes larger than 16k fail on some devices (seed with 3.10.49-g209ea2f in particular).
|
|
||||||
#define USB_FFS_MAX_WRITE 16384
|
|
||||||
|
|
||||||
// The kernel allocates a contiguous buffer for reads, which can fail for large ones due to
|
|
||||||
// fragmentation. 16k chosen arbitrarily to match the write limit.
|
|
||||||
#define USB_FFS_MAX_READ 16384
|
|
||||||
|
|
||||||
struct usb_handle {
|
struct usb_handle {
|
||||||
usb_handle() : kicked(false) {
|
usb_handle() : kicked(false) {
|
||||||
}
|
}
|
||||||
|
|
@ -45,6 +38,8 @@ struct usb_handle {
|
||||||
int control = -1;
|
int control = -1;
|
||||||
int bulk_out = -1; /* "out" from the host's perspective => source for adbd */
|
int bulk_out = -1; /* "out" from the host's perspective => source for adbd */
|
||||||
int bulk_in = -1; /* "in" from the host's perspective => sink for adbd */
|
int bulk_in = -1; /* "in" from the host's perspective => sink for adbd */
|
||||||
|
|
||||||
|
int max_rw;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool init_functionfs(struct usb_handle* h);
|
bool init_functionfs(struct usb_handle* h);
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,15 @@ static int create_service_thread(void (*func)(int, void *), void *cookie)
|
||||||
}
|
}
|
||||||
D("socketpair: (%d,%d)", s[0], s[1]);
|
D("socketpair: (%d,%d)", s[0], s[1]);
|
||||||
|
|
||||||
|
#if !ADB_HOST
|
||||||
|
if (func == &file_sync_service) {
|
||||||
|
// Set file sync service socket to maximum size
|
||||||
|
int max_buf = LINUX_MAX_SOCKET_SIZE;
|
||||||
|
adb_setsockopt(s[0], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
|
||||||
|
adb_setsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
|
||||||
|
}
|
||||||
|
#endif // !ADB_HOST
|
||||||
|
|
||||||
stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
|
stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
|
||||||
if (sti == nullptr) {
|
if (sti == nullptr) {
|
||||||
fatal("cannot allocate stinfo");
|
fatal("cannot allocate stinfo");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue