From 67db78da64b37e8ec17ed91971f8471512efe521 Mon Sep 17 00:00:00 2001 From: Phil Burk Date: Thu, 20 Jun 2019 12:49:01 -0700 Subject: audio_hw: close mmap file descriptor to fix leak The file descriptor for MMAP shared memory was created and passed to AudioFlinger but never closed. Now the FD is closed when the stream is goes to standby. Bug: 134381208 Test: Get HAL pid. Test: adb shell ps | grep audio Test: adb shell ls -l /proc/{halpid}/fd | wc Test: Run Oboetester or other app that uses MMAP Test: Completely close the app. Test: adb shell ls -l /proc/{halpid}/fd | wc Test: Count should NOT grow each time. Change-Id: Ieaaf1c6bdc96e7ecf01cee23215fb39f79662111 --- hal/audio_hw.c | 24 ++++++++++++++++++++++++ hal/audio_hw.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 5d611c6b..0d918d98 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -2817,6 +2817,14 @@ static int out_standby_l(struct audio_stream *stream) if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) { do_stop = out->playback_started; out->playback_started = false; + + if (out->mmap_shared_memory_fd >= 0) { + ALOGV("%s: closing mmap_shared_memory_fd = %d", + __func__, out->mmap_shared_memory_fd); + close(out->mmap_shared_memory_fd); + out->mmap_shared_memory_fd = -1; + } + } } else { stop_compressed_output_l(out); @@ -3989,6 +3997,9 @@ static int out_create_mmap_buffer(const struct audio_stream_out *stream, // Fall back to non exclusive mode info->shared_memory_fd = pcm_get_poll_fd(out->pcm); } else { + out->mmap_shared_memory_fd = info->shared_memory_fd; // for closing later + ALOGV("%s: opened mmap_shared_memory_fd = %d", __func__, out->mmap_shared_memory_fd); + if (mmap_size < buffer_size) { step = "mmap"; goto exit; @@ -4122,6 +4133,14 @@ static int in_standby(struct audio_stream *stream) if (in->usecase == USECASE_AUDIO_RECORD_MMAP) { do_stop = in->capture_started; in->capture_started = false; + + if (in->mmap_shared_memory_fd >= 0) { + ALOGV("%s: closing mmap_shared_memory_fd = %d", + __func__, in->mmap_shared_memory_fd); + close(in->mmap_shared_memory_fd); + in->mmap_shared_memory_fd = -1; + } + } if (in->pcm) { pcm_close(in->pcm); @@ -4718,6 +4737,9 @@ static int in_create_mmap_buffer(const struct audio_stream_in *stream, // Fall back to non exclusive mode info->shared_memory_fd = pcm_get_poll_fd(in->pcm); } else { + in->mmap_shared_memory_fd = info->shared_memory_fd; // for closing later + ALOGV("%s: opened mmap_shared_memory_fd = %d", __func__, in->mmap_shared_memory_fd); + if (mmap_size < buffer_size) { step = "mmap"; goto exit; @@ -4930,6 +4952,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, out->dev = adev; out->handle = handle; out->a2dp_compress_mute = false; + out->mmap_shared_memory_fd = -1; // not open /* Init use case and pcm_config */ if ((is_hdmi || is_usb_dev) && @@ -5893,6 +5916,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->flags = flags; in->direction = MIC_DIRECTION_UNSPECIFIED; in->zoom = 0; + in->mmap_shared_memory_fd = -1; // not open list_init(&in->aec_list); list_init(&in->ns_list); diff --git a/hal/audio_hw.h b/hal/audio_hw.h index 54ee72c5..15cfa604 100644 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -234,6 +234,7 @@ struct stream_out { bool muted; uint64_t written; /* total frames written, not cleared when entering standby */ int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */ + int mmap_shared_memory_fd; /* file descriptor associated with MMAP NOIRQ shared memory */ audio_io_handle_t handle; int non_blocking; @@ -293,6 +294,7 @@ struct stream_in { int64_t frames_read; /* total frames read, not cleared when entering standby */ int64_t frames_muted; /* total frames muted, not cleared when entering standby */ int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */ + int mmap_shared_memory_fd; /* file descriptor associated with MMAP NOIRQ shared memory */ audio_io_handle_t capture_handle; audio_input_flags_t flags; -- cgit v1.2.3