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 <joelaf@google.com>
This commit is contained in:
parent
a73ea65c5a
commit
56cd651e7a
1 changed files with 11 additions and 25 deletions
|
@ -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<uint32_t>(offset), static_cast<uint32_t>(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<uint32_t>(offset), static_cast<uint32_t>(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)));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue