const char *udev_busid = dev_name(&udev->dev);
        struct bus_id_priv *busid_priv;
        int rc = 0;
+       char save_status;
 
        dev_dbg(&udev->dev, "Enter probe\n");
 
+       /* Not sure if this is our device. Allocate here to avoid
+        * calling alloc while holding busid_table lock.
+        */
+       sdev = stub_device_alloc(udev);
+       if (!sdev)
+               return -ENOMEM;
+
        /* check we should claim or not by busid_table */
        busid_priv = get_busid_priv(udev_busid);
        if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
                 * See driver_probe_device() in driver/base/dd.c
                 */
                rc = -ENODEV;
-               goto call_put_busid_priv;
+               goto sdev_free;
        }
 
        if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
                dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n",
                         udev_busid);
                rc = -ENODEV;
-               goto call_put_busid_priv;
+               goto sdev_free;
        }
 
        if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
                        udev_busid);
 
                rc = -ENODEV;
-               goto call_put_busid_priv;
+               goto sdev_free;
        }
 
-       /* ok, this is my device */
-       sdev = stub_device_alloc(udev);
-       if (!sdev) {
-               rc = -ENOMEM;
-               goto call_put_busid_priv;
-       }
 
        dev_info(&udev->dev,
                "usbip-host: register new device (bus %u dev %u)\n",
 
        /* set private data to usb_device */
        dev_set_drvdata(&udev->dev, sdev);
+
        busid_priv->sdev = sdev;
        busid_priv->udev = udev;
 
+       save_status = busid_priv->status;
+       busid_priv->status = STUB_BUSID_ALLOC;
+
        /*
         * Claim this hub port.
         * It doesn't matter what value we pass as owner
                goto err_port;
        }
 
+       /* release the busid_lock */
+       put_busid_priv(busid_priv);
+
        rc = stub_add_files(&udev->dev);
        if (rc) {
                dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid);
                goto err_files;
        }
-       busid_priv->status = STUB_BUSID_ALLOC;
 
-       rc = 0;
-       goto call_put_busid_priv;
+       return 0;
 
 err_files:
        usb_hub_release_port(udev->parent, udev->portnum,
        dev_set_drvdata(&udev->dev, NULL);
        usb_put_dev(udev);
 
+       /* we already have busid_priv, just lock busid_lock */
+       spin_lock(&busid_priv->busid_lock);
        busid_priv->sdev = NULL;
+       busid_priv->status = save_status;
+sdev_free:
        stub_device_free(sdev);
-
-call_put_busid_priv:
+       /* release the busid_lock */
        put_busid_priv(busid_priv);
+
        return rc;
 }
 
 static void shutdown_busid(struct bus_id_priv *busid_priv)
 {
-       if (busid_priv->sdev && !busid_priv->shutdown_busid) {
-               busid_priv->shutdown_busid = 1;
-               usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
+       usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
 
-               /* wait for the stop of the event handler */
-               usbip_stop_eh(&busid_priv->sdev->ud);
-       }
+       /* wait for the stop of the event handler */
+       usbip_stop_eh(&busid_priv->sdev->ud);
 }
 
 /*
 
        dev_set_drvdata(&udev->dev, NULL);
 
+       /* release busid_lock before call to remove device files */
+       put_busid_priv(busid_priv);
+
        /*
         * NOTE: rx/tx threads are invoked for each usb_device.
         */
                                  (struct usb_dev_state *) udev);
        if (rc) {
                dev_dbg(&udev->dev, "unable to release port\n");
-               goto call_put_busid_priv;
+               return;
        }
 
        /* If usb reset is called from event handler */
        if (usbip_in_eh(current))
-               goto call_put_busid_priv;
+               return;
+
+       /* we already have busid_priv, just lock busid_lock */
+       spin_lock(&busid_priv->busid_lock);
+       if (!busid_priv->shutdown_busid)
+               busid_priv->shutdown_busid = 1;
+       /* release busid_lock */
+       put_busid_priv(busid_priv);
 
        /* shutdown the current connection */
        shutdown_busid(busid_priv);
 
        usb_put_dev(sdev->udev);
 
+       /* we already have busid_priv, just lock busid_lock */
+       spin_lock(&busid_priv->busid_lock);
        /* free sdev */
        busid_priv->sdev = NULL;
        stub_device_free(sdev);
                busid_priv->status = STUB_BUSID_ADDED;
 
 call_put_busid_priv:
+       /* release busid_lock */
        put_busid_priv(busid_priv);
 }