console_req is always null when calling gs_console_connect, so
remove check and put access under con_lock as we are racing with
gs_console_thread.

Signed-off-by: Ladislav Michl <la...@linux-mips.org>
---
 Changes:
 - v2: New patch

 drivers/usb/gadget/function/u_serial.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/gadget/function/u_serial.c 
b/drivers/usb/gadget/function/u_serial.c
index cb88a640179e..558a6929ce68 100644
--- a/drivers/usb/gadget/function/u_serial.c
+++ b/drivers/usb/gadget/function/u_serial.c
@@ -930,15 +930,12 @@ static int gs_console_connect(int port_num)
 
        port = ports[port_num].port;
        ep = port->port_usb->in;
-       if (!info->console_req) {
-               info->console_req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
-               if (!info->console_req)
-                       return -ENOMEM;
-               info->console_req->complete = gs_complete_out;
-       }
-
-       info->port = port;
        spin_lock(&info->con_lock);
+       info->console_req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
+       if (!info->console_req)
+               return -ENOMEM;
+       info->console_req->complete = gs_complete_out;
+       info->port = port;
        info->req_busy = 0;
        spin_unlock(&info->con_lock);
        pr_vdebug("port[%d] console connect!\n", port_num);
@@ -948,10 +945,11 @@ static int gs_console_connect(int port_num)
 static void gs_console_disconnect(struct usb_ep *ep)
 {
        struct gscons_info *info = &gscons_info;
-       struct usb_request *req = info->console_req;
 
-       gs_free_req(ep, req);
+       spin_lock(&info->con_lock);
+       gs_free_req(ep, info->console_req);
        info->console_req = NULL;
+       spin_unlock(&info->con_lock);
 }
 
 static int gs_console_thread(void *data)
@@ -1008,7 +1006,6 @@ static int gs_console_setup(struct console *co, char 
*options)
        info->port = NULL;
        info->console_req = NULL;
        info->req_busy = 0;
-       spin_lock_init(&info->con_lock);
 
        status = kfifo_alloc(&info->con_buf, GS_CONSOLE_BUF_SIZE, GFP_KERNEL);
        if (status) {
@@ -1064,6 +1061,9 @@ static struct console gserial_cons = {
 
 static void gserial_console_init(void)
 {
+       struct gscons_info *info = &gscons_info;
+
+       spin_lock_init(&info->con_lock);
        register_console(&gserial_cons);
 }
 
-- 
2.22.0

Reply via email to