From: he.he Date: Tue, 20 Nov 2018 05:57:37 +0000 (+0800) Subject: usb: adb panic [1/1] X-Git-Tag: hardkernel-4.9.236-104~2041 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ed988b87f0c744b5f8912271ea3b24c43cc6db3c;p=platform%2Fkernel%2Flinux-amlogic.git usb: adb panic [1/1] PD#SWPL-2678 Problem: adb panic in release_ffs_buffer Solution: 1.when kzalloc data_ep use GFP_ATOMIC instead of GFP_KERNEL and keep spin lock protection. 2.check buffer_temp->data_ep == NULL, return Test: adb push Verify: verified by he he Change-Id: I3402b17d62b8a0ef4e3185a87729a0c3e87449e9 Signed-off-by: he.he --- diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 35d66f5..32c2999 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -294,10 +294,8 @@ struct ffs_data_buffer *ffs_retry_malloc_buffer(struct ffs_data *ffs) pr_info("ffs_retry_malloc_buffer\n"); for (i = 0; i < FFS_BUFFER_MAX; i++) { if (ffs->buffer[i].data_state == -1) { - spin_unlock_irq(&ffs->eps_lock); ffs->buffer[i].data_ep - = kzalloc(MAX_PAYLOAD_EPS, GFP_KERNEL); - spin_lock_irq(&ffs->eps_lock); + = kzalloc(MAX_PAYLOAD_EPS, GFP_ATOMIC); if (!ffs->buffer[i].data_ep) return NULL; ffs->buffer[i].data_state = 1; @@ -317,7 +315,7 @@ static void ffs_free_buffer(struct ffs_data *ffs) if (ffs->buffer[i].data_state != -1) { kfree(ffs->buffer[i].data_ep); ffs->buffer[i].data_ep = NULL; - ffs->buffer[i].data_state = 0; + ffs->buffer[i].data_state = -1; } } } @@ -342,6 +340,11 @@ static void release_ffs_buffer(struct ffs_data *ffs, struct ffs_data_buffer *buffer_temp = buffer; spin_lock_irq(&ffs->eps_lock); + if (buffer_temp->data_ep == NULL) { + buffer_temp->data_state = -1; + spin_unlock_irq(&ffs->eps_lock); + return; + } memset(buffer_temp->data_ep, 0, MAX_PAYLOAD_EPS); buffer_temp->data_state = 0; spin_unlock_irq(&ffs->eps_lock); @@ -872,6 +875,10 @@ static void ffs_user_copy_worker(struct work_struct *work) if (io_data->buf == buffer->data_ep) { break; } + if (i == FFS_BUFFER_MAX - 1) { + pr_info("io_data->buf is missing, i=%d-\n", i); + buffer = NULL; + } } #endif if (io_data->read && ret > 0) {