diff options
author | Todd Kjos <tkjos@android.com> | 2017-06-29 15:01:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-07-17 08:47:29 -0400 |
commit | 57ada2fb2250eab5abe381353f12ada337d82808 (patch) | |
tree | 8a67a3bd356b43e5591a8c3c378d39701a25bd38 /drivers/android/binder_alloc.c | |
parent | 656a800aad6051ccc81b26c388a2a7a1c8cc8c81 (diff) |
binder: add log information for binder transaction failures
Add additional information to determine the cause of binder
failures. Adds the following to failed transaction log and
kernel messages:
return_error : value returned for transaction
return_error_param : errno returned by binder allocator
return_error_line : line number where error detected
Also, return BR_DEAD_REPLY if an allocation error indicates
a dead proc (-ESRCH)
Signed-off-by: Todd Kjos <tkjos@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/android/binder_alloc.c')
-rw-r--r-- | drivers/android/binder_alloc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 198d04c5d958..a0af1419cc79 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c | |||
@@ -262,7 +262,7 @@ err_no_vma: | |||
262 | up_write(&mm->mmap_sem); | 262 | up_write(&mm->mmap_sem); |
263 | mmput(mm); | 263 | mmput(mm); |
264 | } | 264 | } |
265 | return -ENOMEM; | 265 | return vma ? -ENOMEM : -ESRCH; |
266 | } | 266 | } |
267 | 267 | ||
268 | struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, | 268 | struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, |
@@ -278,11 +278,12 @@ struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, | |||
278 | void *has_page_addr; | 278 | void *has_page_addr; |
279 | void *end_page_addr; | 279 | void *end_page_addr; |
280 | size_t size, data_offsets_size; | 280 | size_t size, data_offsets_size; |
281 | int ret; | ||
281 | 282 | ||
282 | if (alloc->vma == NULL) { | 283 | if (alloc->vma == NULL) { |
283 | pr_err("%d: binder_alloc_buf, no vma\n", | 284 | pr_err("%d: binder_alloc_buf, no vma\n", |
284 | alloc->pid); | 285 | alloc->pid); |
285 | return NULL; | 286 | return ERR_PTR(-ESRCH); |
286 | } | 287 | } |
287 | 288 | ||
288 | data_offsets_size = ALIGN(data_size, sizeof(void *)) + | 289 | data_offsets_size = ALIGN(data_size, sizeof(void *)) + |
@@ -292,21 +293,21 @@ struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, | |||
292 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, | 293 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, |
293 | "%d: got transaction with invalid size %zd-%zd\n", | 294 | "%d: got transaction with invalid size %zd-%zd\n", |
294 | alloc->pid, data_size, offsets_size); | 295 | alloc->pid, data_size, offsets_size); |
295 | return NULL; | 296 | return ERR_PTR(-EINVAL); |
296 | } | 297 | } |
297 | size = data_offsets_size + ALIGN(extra_buffers_size, sizeof(void *)); | 298 | size = data_offsets_size + ALIGN(extra_buffers_size, sizeof(void *)); |
298 | if (size < data_offsets_size || size < extra_buffers_size) { | 299 | if (size < data_offsets_size || size < extra_buffers_size) { |
299 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, | 300 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, |
300 | "%d: got transaction with invalid extra_buffers_size %zd\n", | 301 | "%d: got transaction with invalid extra_buffers_size %zd\n", |
301 | alloc->pid, extra_buffers_size); | 302 | alloc->pid, extra_buffers_size); |
302 | return NULL; | 303 | return ERR_PTR(-EINVAL); |
303 | } | 304 | } |
304 | if (is_async && | 305 | if (is_async && |
305 | alloc->free_async_space < size + sizeof(struct binder_buffer)) { | 306 | alloc->free_async_space < size + sizeof(struct binder_buffer)) { |
306 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, | 307 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, |
307 | "%d: binder_alloc_buf size %zd failed, no async space left\n", | 308 | "%d: binder_alloc_buf size %zd failed, no async space left\n", |
308 | alloc->pid, size); | 309 | alloc->pid, size); |
309 | return NULL; | 310 | return ERR_PTR(-ENOSPC); |
310 | } | 311 | } |
311 | 312 | ||
312 | while (n) { | 313 | while (n) { |
@@ -327,7 +328,7 @@ struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, | |||
327 | if (best_fit == NULL) { | 328 | if (best_fit == NULL) { |
328 | pr_err("%d: binder_alloc_buf size %zd failed, no address space\n", | 329 | pr_err("%d: binder_alloc_buf size %zd failed, no address space\n", |
329 | alloc->pid, size); | 330 | alloc->pid, size); |
330 | return NULL; | 331 | return ERR_PTR(-ENOSPC); |
331 | } | 332 | } |
332 | if (n == NULL) { | 333 | if (n == NULL) { |
333 | buffer = rb_entry(best_fit, struct binder_buffer, rb_node); | 334 | buffer = rb_entry(best_fit, struct binder_buffer, rb_node); |
@@ -350,9 +351,10 @@ struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, | |||
350 | (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); | 351 | (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); |
351 | if (end_page_addr > has_page_addr) | 352 | if (end_page_addr > has_page_addr) |
352 | end_page_addr = has_page_addr; | 353 | end_page_addr = has_page_addr; |
353 | if (binder_update_page_range(alloc, 1, | 354 | ret = binder_update_page_range(alloc, 1, |
354 | (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)) | 355 | (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL); |
355 | return NULL; | 356 | if (ret) |
357 | return ERR_PTR(ret); | ||
356 | 358 | ||
357 | rb_erase(best_fit, &alloc->free_buffers); | 359 | rb_erase(best_fit, &alloc->free_buffers); |
358 | buffer->free = 0; | 360 | buffer->free = 0; |