Message ID | 1432027840-18711-9-git-send-email-vinod.koul@intel.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 859c34bd3cabfc79106f9fcb5c55fb4af3eb3ce2 |
Headers | show |
At Tue, 19 May 2015 15:00:40 +0530, Vinod Koul wrote: > > From: "Subhransu S. Prusty" <subhransu.s.prusty@intel.com> > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com> > Signed-off-by: Vinod Koul <vinod.koul@intel.com> > --- > sound/soc/intel/common/sst-ipc.c | 29 ++++++++++++++++++++++++++++- > sound/soc/intel/common/sst-ipc.h | 4 ++-- > 2 files changed, 30 insertions(+), 3 deletions(-) > > diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c > index a7699f35a8d2..a12c7bb08d3b 100644 > --- a/sound/soc/intel/common/sst-ipc.c > +++ b/sound/soc/intel/common/sst-ipc.c > @@ -129,11 +129,31 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) > return -ENOMEM; > > for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { > + ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); > + if (ipc->msg[i].tx_data == NULL) > + goto free_mem; > + > + ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); > + if (ipc->msg[i].rx_data == NULL) { > + kfree(ipc->msg[i].tx_data); > + goto free_mem; > + } > + > init_waitqueue_head(&ipc->msg[i].waitq); > list_add(&ipc->msg[i].list, &ipc->empty_list); Wouldn't this leave stale linked list entries at error? Takashi > } > > return 0; > + > +free_mem: > + while (i > 0) { > + kfree(ipc->msg[i-1].tx_data); > + kfree(ipc->msg[i-1].rx_data); > + --i; > + } > + kfree(ipc->msg); > + > + return -ENOMEM; > } > > static void ipc_tx_msgs(struct kthread_work *work) > @@ -279,11 +299,18 @@ EXPORT_SYMBOL_GPL(sst_ipc_init); > > void sst_ipc_fini(struct sst_generic_ipc *ipc) > { > + int i; > + > if (ipc->tx_thread) > kthread_stop(ipc->tx_thread); > > - if (ipc->msg) > + if (ipc->msg) { > + for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { > + kfree(ipc->msg[i].tx_data); > + kfree(ipc->msg[i].rx_data); > + } > kfree(ipc->msg); > + } > } > EXPORT_SYMBOL_GPL(sst_ipc_fini); > > diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h > index 7139afd2547f..ceb7e468a3fa 100644 > --- a/sound/soc/intel/common/sst-ipc.h > +++ b/sound/soc/intel/common/sst-ipc.h > @@ -32,9 +32,9 @@ struct ipc_message { > u64 header; > > /* direction wrt host CPU */ > - char tx_data[IPC_MAX_MAILBOX_BYTES]; > + char *tx_data; > size_t tx_size; > - char rx_data[IPC_MAX_MAILBOX_BYTES]; > + char *rx_data; > size_t rx_size; > > wait_queue_head_t waitq; > -- > 1.9.1 >
On Tue, May 19, 2015 at 12:42:03PM +0200, Takashi Iwai wrote: > At Tue, 19 May 2015 15:00:40 +0530, > Vinod Koul wrote: > > > > From: "Subhransu S. Prusty" <subhransu.s.prusty@intel.com> > > > > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com> > > Signed-off-by: Vinod Koul <vinod.koul@intel.com> > > --- > > sound/soc/intel/common/sst-ipc.c | 29 ++++++++++++++++++++++++++++- > > sound/soc/intel/common/sst-ipc.h | 4 ++-- > > 2 files changed, 30 insertions(+), 3 deletions(-) > > > > diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c > > index a7699f35a8d2..a12c7bb08d3b 100644 > > --- a/sound/soc/intel/common/sst-ipc.c > > +++ b/sound/soc/intel/common/sst-ipc.c > > @@ -129,11 +129,31 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) > > return -ENOMEM; > > > > for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { > > + ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); > > + if (ipc->msg[i].tx_data == NULL) > > + goto free_mem; > > + > > + ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); > > + if (ipc->msg[i].rx_data == NULL) { > > + kfree(ipc->msg[i].tx_data); > > + goto free_mem; > > + } > > + > > init_waitqueue_head(&ipc->msg[i].waitq); > > list_add(&ipc->msg[i].list, &ipc->empty_list); > > Wouldn't this leave stale linked list entries at error? Yes it will, but this is happening at device probe, so the probe will fail and device will no longer be usable. We do free the memory so shouldn't leak.
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c index a7699f35a8d2..a12c7bb08d3b 100644 --- a/sound/soc/intel/common/sst-ipc.c +++ b/sound/soc/intel/common/sst-ipc.c @@ -129,11 +129,31 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) return -ENOMEM; for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { + ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); + if (ipc->msg[i].tx_data == NULL) + goto free_mem; + + ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); + if (ipc->msg[i].rx_data == NULL) { + kfree(ipc->msg[i].tx_data); + goto free_mem; + } + init_waitqueue_head(&ipc->msg[i].waitq); list_add(&ipc->msg[i].list, &ipc->empty_list); } return 0; + +free_mem: + while (i > 0) { + kfree(ipc->msg[i-1].tx_data); + kfree(ipc->msg[i-1].rx_data); + --i; + } + kfree(ipc->msg); + + return -ENOMEM; } static void ipc_tx_msgs(struct kthread_work *work) @@ -279,11 +299,18 @@ EXPORT_SYMBOL_GPL(sst_ipc_init); void sst_ipc_fini(struct sst_generic_ipc *ipc) { + int i; + if (ipc->tx_thread) kthread_stop(ipc->tx_thread); - if (ipc->msg) + if (ipc->msg) { + for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { + kfree(ipc->msg[i].tx_data); + kfree(ipc->msg[i].rx_data); + } kfree(ipc->msg); + } } EXPORT_SYMBOL_GPL(sst_ipc_fini); diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h index 7139afd2547f..ceb7e468a3fa 100644 --- a/sound/soc/intel/common/sst-ipc.h +++ b/sound/soc/intel/common/sst-ipc.h @@ -32,9 +32,9 @@ struct ipc_message { u64 header; /* direction wrt host CPU */ - char tx_data[IPC_MAX_MAILBOX_BYTES]; + char *tx_data; size_t tx_size; - char rx_data[IPC_MAX_MAILBOX_BYTES]; + char *rx_data; size_t rx_size; wait_queue_head_t waitq;