diff options
author | Joel Fernandes | 2018-07-17 15:00:17 -0500 |
---|---|---|
committer | Joel Fernandes | 2018-07-17 19:02:44 -0500 |
commit | 56cd651e7ae16173f9c24fd49cd76e8c61f0756c (patch) | |
tree | c3cd72df12cf9435fd0da938e712e58054d3896b | |
parent | a73ea65c5aa40fbd3faf05ece4de4c7acc7a8564 (diff) | |
download | platform-system-core-56cd651e7ae16173f9c24fd49cd76e8c61f0756c.tar.gz platform-system-core-56cd651e7ae16173f9c24fd49cd76e8c61f0756c.tar.xz platform-system-core-56cd651e7ae16173f9c24fd49cd76e8c61f0756c.zip |
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>
-rw-r--r-- | libcutils/ashmem-dev.cpp | 36 |
1 files changed, 11 insertions, 25 deletions
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) | |||
90 | dev_t rdev; | 90 | dev_t rdev; |
91 | struct stat st; | 91 | struct stat st; |
92 | 92 | ||
93 | if (TEMP_FAILURE_RETRY(fstat(fd, &st)) < 0) { | 93 | if (fstat(fd, &st) < 0) { |
94 | return -1; | 94 | return -1; |
95 | } | 95 | } |
96 | 96 | ||
@@ -135,6 +135,12 @@ static int __ashmem_is_ashmem(int fd, int fatal) | |||
135 | return -1; | 135 | return -1; |
136 | } | 136 | } |
137 | 137 | ||
138 | static int __ashmem_check_failure(int fd, int result) | ||
139 | { | ||
140 | if (result == -1 && errno == ENOTTY) __ashmem_is_ashmem(fd, 1); | ||
141 | return result; | ||
142 | } | ||
143 | |||
138 | int ashmem_valid(int fd) | 144 | int ashmem_valid(int fd) |
139 | { | 145 | { |
140 | return __ashmem_is_ashmem(fd, 0) >= 0; | 146 | return __ashmem_is_ashmem(fd, 0) >= 0; |
@@ -182,12 +188,7 @@ error: | |||
182 | 188 | ||
183 | int ashmem_set_prot_region(int fd, int prot) | 189 | int ashmem_set_prot_region(int fd, int prot) |
184 | { | 190 | { |
185 | int ret = __ashmem_is_ashmem(fd, 1); | 191 | return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot))); |
186 | if (ret < 0) { | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot)); | ||
191 | } | 192 | } |
192 | 193 | ||
193 | int ashmem_pin_region(int fd, size_t offset, size_t len) | 194 | 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) | |||
195 | // TODO: should LP64 reject too-large offset/len? | 196 | // TODO: should LP64 reject too-large offset/len? |
196 | ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) }; | 197 | ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) }; |
197 | 198 | ||
198 | int ret = __ashmem_is_ashmem(fd, 1); | 199 | return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin))); |
199 | if (ret < 0) { | ||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin)); | ||
204 | } | 200 | } |
205 | 201 | ||
206 | int ashmem_unpin_region(int fd, size_t offset, size_t len) | 202 | 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) | |||
208 | // TODO: should LP64 reject too-large offset/len? | 204 | // TODO: should LP64 reject too-large offset/len? |
209 | ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) }; | 205 | ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) }; |
210 | 206 | ||
211 | int ret = __ashmem_is_ashmem(fd, 1); | 207 | return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin))); |
212 | if (ret < 0) { | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin)); | ||
217 | } | 208 | } |
218 | 209 | ||
219 | int ashmem_get_size_region(int fd) | 210 | int ashmem_get_size_region(int fd) |
220 | { | 211 | { |
221 | int ret = __ashmem_is_ashmem(fd, 1); | 212 | return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL))); |
222 | if (ret < 0) { | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL)); | ||
227 | } | 213 | } |