From 56cd651e7ae16173f9c24fd49cd76e8c61f0756c Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Tue, 17 Jul 2018 13:00:17 -0700 Subject: libcutils: ashmem: Avoid doing fd checks for ashmem calls Callers already verify that they are calling ashmem API on a valid fd by calling ashmem_valid first. Lets make the fstat syscall only if the ioctl returns -ENOTTY. This means in the regular case, only 1 syscall is needed (ioctl) vs the current 2 (fstat+ioctl). Some data to show improvements in reduction of vfs_getattr calls in the kernel by 10x when doing a camera. Test: Boot and camera CTS Bug: 111418894 Change-Id: I992620bbe44355e54ba19eeac81da586c5e5a6e0 Signed-off-by: Joel Fernandes --- libcutils/ashmem-dev.cpp | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) (limited to 'libcutils/ashmem-dev.cpp') diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp index 15ace0e64..0cc4fc084 100644 --- a/libcutils/ashmem-dev.cpp +++ b/libcutils/ashmem-dev.cpp @@ -90,7 +90,7 @@ static int __ashmem_is_ashmem(int fd, int fatal) dev_t rdev; struct stat st; - if (TEMP_FAILURE_RETRY(fstat(fd, &st)) < 0) { + if (fstat(fd, &st) < 0) { return -1; } @@ -135,6 +135,12 @@ static int __ashmem_is_ashmem(int fd, int fatal) return -1; } +static int __ashmem_check_failure(int fd, int result) +{ + if (result == -1 && errno == ENOTTY) __ashmem_is_ashmem(fd, 1); + return result; +} + int ashmem_valid(int fd) { return __ashmem_is_ashmem(fd, 0) >= 0; @@ -182,12 +188,7 @@ error: int ashmem_set_prot_region(int fd, int prot) { - int ret = __ashmem_is_ashmem(fd, 1); - if (ret < 0) { - return ret; - } - - return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot)); + return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot))); } int ashmem_pin_region(int fd, size_t offset, size_t len) @@ -195,12 +196,7 @@ int ashmem_pin_region(int fd, size_t offset, size_t len) // TODO: should LP64 reject too-large offset/len? ashmem_pin pin = { static_cast(offset), static_cast(len) }; - int ret = __ashmem_is_ashmem(fd, 1); - if (ret < 0) { - return ret; - } - - return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin)); + return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin))); } int ashmem_unpin_region(int fd, size_t offset, size_t len) @@ -208,20 +204,10 @@ int ashmem_unpin_region(int fd, size_t offset, size_t len) // TODO: should LP64 reject too-large offset/len? ashmem_pin pin = { static_cast(offset), static_cast(len) }; - int ret = __ashmem_is_ashmem(fd, 1); - if (ret < 0) { - return ret; - } - - return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin)); + return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin))); } int ashmem_get_size_region(int fd) { - int ret = __ashmem_is_ashmem(fd, 1); - if (ret < 0) { - return ret; - } - - return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL)); + return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL))); } -- cgit v1.2.3