aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@nxp.com>2018-06-11 21:53:01 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-06-25 09:43:35 -0400
commitd5a4f93511b7000183c0d528739b824752139f79 (patch)
tree95ecd4250882946da72f1527df6c1d14e26e0666
parent9578bcd0bb487b8ecef4b7eee799aafb678aa441 (diff)
usb: typec: tcpm: fix logbuffer index is wrong if _tcpm_log is re-entered
The port->logbuffer_head may be wrong if the two processes enters _tcpm_log at the mostly same time. The 2nd process enters _tcpm_log before the 1st process update the index, then the 2nd process will not allocate logbuffer, when the 2nd process tries to use log buffer, the index has already updated by the 1st process, so it will get NULL pointer for updated logbuffer, the error message like below: tcpci 0-0050: Log buffer index 6 is NULL Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com> Cc: Guenter Roeck <linux@roeck-us.net> Cc: Jun Li <jun.li@nxp.com> Signed-off-by: Peter Chen <peter.chen@nxp.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Cc: stable <stable@vger.kernel.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/typec/tcpm.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
index 0dfd755020f4..d961f1ec0e08 100644
--- a/drivers/usb/typec/tcpm.c
+++ b/drivers/usb/typec/tcpm.c
@@ -418,17 +418,18 @@ static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args)
418 u64 ts_nsec = local_clock(); 418 u64 ts_nsec = local_clock();
419 unsigned long rem_nsec; 419 unsigned long rem_nsec;
420 420
421 mutex_lock(&port->logbuffer_lock);
421 if (!port->logbuffer[port->logbuffer_head]) { 422 if (!port->logbuffer[port->logbuffer_head]) {
422 port->logbuffer[port->logbuffer_head] = 423 port->logbuffer[port->logbuffer_head] =
423 kzalloc(LOG_BUFFER_ENTRY_SIZE, GFP_KERNEL); 424 kzalloc(LOG_BUFFER_ENTRY_SIZE, GFP_KERNEL);
424 if (!port->logbuffer[port->logbuffer_head]) 425 if (!port->logbuffer[port->logbuffer_head]) {
426 mutex_unlock(&port->logbuffer_lock);
425 return; 427 return;
428 }
426 } 429 }
427 430
428 vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args); 431 vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
429 432
430 mutex_lock(&port->logbuffer_lock);
431
432 if (tcpm_log_full(port)) { 433 if (tcpm_log_full(port)) {
433 port->logbuffer_head = max(port->logbuffer_head - 1, 0); 434 port->logbuffer_head = max(port->logbuffer_head - 1, 0);
434 strcpy(tmpbuffer, "overflow"); 435 strcpy(tmpbuffer, "overflow");