Print this page
XXXX don't fail device detach when it's physically removed

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/scsi/targets/sd.c
          +++ new/usr/src/uts/common/io/scsi/targets/sd.c
↓ open down ↓ 8543 lines elided ↑ open up ↑
8544 8544  static int
8545 8545  sd_unit_detach(dev_info_t *devi)
8546 8546  {
8547 8547          struct scsi_device      *devp;
8548 8548          struct sd_lun           *un;
8549 8549          int                     i;
8550 8550          int                     tgt;
8551 8551          dev_t                   dev;
8552 8552          dev_info_t              *pdip = ddi_get_parent(devi);
8553 8553          int                     instance = ddi_get_instance(devi);
     8554 +        int                     devigone = DEVI(devi)->devi_gone;
8554 8555  
8555 8556          mutex_enter(&sd_detach_mutex);
8556 8557  
8557 8558          /*
8558 8559           * Fail the detach for any of the following:
8559      -         *  - Unable to get the sd_lun struct for the instance
8560      -         *  - A layered driver has an outstanding open on the instance
8561      -         *  - Another thread is already detaching this instance
8562      -         *  - Another thread is currently performing an open
     8560 +         * - Unable to get the sd_lun struct for the instance
     8561 +         * - Another thread is already detaching this instance
     8562 +         * - Another thread is currently performing an open
     8563 +         *
     8564 +         * Additionaly, if "device gone" flag is not set:
     8565 +         * - There are outstanding commands in driver
     8566 +         * - There are outstanding commands in transport
8563 8567           */
8564 8568          devp = ddi_get_driver_private(devi);
8565      -        if ((devp == NULL) ||
8566      -            ((un = (struct sd_lun *)devp->sd_private) == NULL) ||
8567      -            (un->un_ncmds_in_driver != 0) || (un->un_layer_count != 0) ||
8568      -            (un->un_detach_count != 0) || (un->un_opens_in_progress != 0)) {
     8569 +        if (devp == NULL || (un = (struct sd_lun *)devp->sd_private) == NULL ||
     8570 +            un->un_detach_count != 0 || un->un_opens_in_progress != 0 ||
     8571 +            (!devigone && (un->un_ncmds_in_driver != 0 ||
     8572 +            un->un_ncmds_in_transport != 0 ||
     8573 +            un->un_state == SD_STATE_RWAIT))) {
8569 8574                  mutex_exit(&sd_detach_mutex);
8570 8575                  return (DDI_FAILURE);
8571 8576          }
8572 8577  
8573      -        SD_TRACE(SD_LOG_ATTACH_DETACH, un, "sd_unit_detach: entry 0x%p\n", un);
     8578 +        SD_TRACE(SD_LOG_ATTACH_DETACH, un, "%s: entry 0x%p\n", __func__, un);
8574 8579  
8575 8580          /*
8576 8581           * Mark this instance as currently in a detach, to inhibit any
8577 8582           * opens from a layered driver.
8578 8583           */
8579 8584          un->un_detach_count++;
8580 8585          mutex_exit(&sd_detach_mutex);
8581 8586  
8582 8587          tgt = ddi_prop_get_int(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
8583 8588              SCSI_ADDR_PROP_TARGET, -1);
8584 8589  
8585 8590          dev = sd_make_device(SD_DEVINFO(un));
8586 8591  
8587      -#ifndef lint
8588      -        _NOTE(COMPETING_THREADS_NOW);
8589      -#endif
8590      -
8591 8592          mutex_enter(SD_MUTEX(un));
8592 8593  
8593 8594          /*
8594 8595           * Fail the detach if there are any outstanding layered
8595 8596           * opens on this device.
8596 8597           */
8597 8598          for (i = 0; i < NDKMAP; i++) {
8598 8599                  if (un->un_ocmap.lyropen[i] != 0) {
8599 8600                          goto err_notclosed;
8600 8601                  }
8601 8602          }
8602 8603  
8603 8604          /*
8604      -         * Verify there are NO outstanding commands issued to this device.
8605      -         * ie, un_ncmds_in_transport == 0.
8606      -         * It's possible to have outstanding commands through the physio
8607      -         * code path, even though everything's closed.
8608      -         */
8609      -        if ((un->un_ncmds_in_transport != 0) || (un->un_retry_timeid != NULL) ||
8610      -            (un->un_direct_priority_timeid != NULL) ||
8611      -            (un->un_state == SD_STATE_RWAIT)) {
8612      -                mutex_exit(SD_MUTEX(un));
8613      -                SD_ERROR(SD_LOG_ATTACH_DETACH, un,
8614      -                    "sd_dr_detach: Detach failure due to outstanding cmds\n");
8615      -                goto err_stillbusy;
8616      -        }
8617      -
8618      -        /*
8619 8605           * If we have the device reserved, release the reservation.
8620 8606           */
8621      -        if ((un->un_resvd_status & SD_RESERVE) &&
     8607 +        if (!devigone &&
     8608 +            (un->un_resvd_status & SD_RESERVE) &&
8622 8609              !(un->un_resvd_status & SD_LOST_RESERVE)) {
8623 8610                  mutex_exit(SD_MUTEX(un));
8624 8611                  /*
8625 8612                   * Note: sd_reserve_release sends a command to the device
8626 8613                   * via the sd_ioctlcmd() path, and can sleep.
8627 8614                   */
8628 8615                  if (sd_reserve_release(dev, SD_RELEASE) != 0) {
8629 8616                          SD_ERROR(SD_LOG_ATTACH_DETACH, un,
8630      -                            "sd_dr_detach: Cannot release reservation \n");
     8617 +                            "%s: cannot release reservation\n", __func__);
8631 8618                  }
8632 8619          } else {
8633 8620                  mutex_exit(SD_MUTEX(un));
8634 8621          }
8635 8622  
8636 8623          /*
8637 8624           * Untimeout any reserve recover, throttle reset, restart unit
8638 8625           * and delayed broadcast timeout threads. Protect the timeout pointer
8639 8626           * from getting nulled by their callback functions.
8640 8627           */
↓ open down ↓ 36 lines elided ↑ open up ↑
8677 8664                  mutex_exit(SD_MUTEX(un));
8678 8665                  (void) untimeout(temp_id);
8679 8666          } else {
8680 8667                  mutex_exit(SD_MUTEX(un));
8681 8668          }
8682 8669  
8683 8670          /* Remove any pending reservation reclaim requests for this device */
8684 8671          sd_rmv_resv_reclaim_req(dev);
8685 8672  
8686 8673          mutex_enter(SD_MUTEX(un));
     8674 +        if (un->un_retry_timeid != NULL) {
     8675 +                timeout_id_t temp_id = un->un_retry_timeid;
     8676 +                un->un_retry_timeid = NULL;
     8677 +                mutex_exit(SD_MUTEX(un));
     8678 +                (void) untimeout(temp_id);
     8679 +                mutex_enter(SD_MUTEX(un));
     8680 +        }
8687 8681  
8688 8682          /* Cancel any pending callbacks for SD_PATH_DIRECT_PRIORITY cmd. */
8689 8683          if (un->un_direct_priority_timeid != NULL) {
8690 8684                  timeout_id_t temp_id = un->un_direct_priority_timeid;
8691 8685                  un->un_direct_priority_timeid = NULL;
8692 8686                  mutex_exit(SD_MUTEX(un));
8693 8687                  (void) untimeout(temp_id);
8694 8688                  mutex_enter(SD_MUTEX(un));
8695 8689          }
8696 8690  
8697 8691          /* Cancel any active multi-host disk watch thread requests */
8698 8692          if (un->un_mhd_token != NULL) {
8699 8693                  mutex_exit(SD_MUTEX(un));
8700 8694                   _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_mhd_token));
8701 8695                  if (scsi_watch_request_terminate(un->un_mhd_token,
8702 8696                      SCSI_WATCH_TERMINATE_NOWAIT)) {
8703 8697                          SD_ERROR(SD_LOG_ATTACH_DETACH, un,
8704      -                            "sd_dr_detach: Cannot cancel mhd watch request\n");
     8698 +                            "%s: cannot cancel mhd watch request\n", __func__);
8705 8699                          /*
8706 8700                           * Note: We are returning here after having removed
8707 8701                           * some driver timeouts above. This is consistent with
8708 8702                           * the legacy implementation but perhaps the watch
8709 8703                           * terminate call should be made with the wait flag set.
8710 8704                           */
8711 8705                          goto err_stillbusy;
8712 8706                  }
8713 8707                  mutex_enter(SD_MUTEX(un));
8714 8708                  un->un_mhd_token = NULL;
8715 8709          }
8716 8710  
8717 8711          if (un->un_swr_token != NULL) {
8718 8712                  mutex_exit(SD_MUTEX(un));
8719 8713                  _NOTE(DATA_READABLE_WITHOUT_LOCK(sd_lun::un_swr_token));
8720 8714                  if (scsi_watch_request_terminate(un->un_swr_token,
8721 8715                      SCSI_WATCH_TERMINATE_NOWAIT)) {
8722 8716                          SD_ERROR(SD_LOG_ATTACH_DETACH, un,
8723      -                            "sd_dr_detach: Cannot cancel swr watch request\n");
     8717 +                            "%s: cannot cancel swr watch request\n", __func__);
8724 8718                          /*
8725 8719                           * Note: We are returning here after having removed
8726 8720                           * some driver timeouts above. This is consistent with
8727 8721                           * the legacy implementation but perhaps the watch
8728 8722                           * terminate call should be made with the wait flag set.
8729 8723                           */
8730 8724                          goto err_stillbusy;
8731 8725                  }
8732 8726                  mutex_enter(SD_MUTEX(un));
8733 8727                  un->un_swr_token = NULL;
8734 8728          }
8735 8729  
8736      -        mutex_exit(SD_MUTEX(un));
8737      -
8738 8730          /*
8739 8731           * Clear any scsi_reset_notifies. We clear the reset notifies
8740 8732           * if we have not registered one.
8741 8733           * Note: The sd_mhd_reset_notify_cb() fn tries to acquire SD_MUTEX!
8742 8734           */
     8735 +        mutex_exit(SD_MUTEX(un));
8743 8736          (void) scsi_reset_notify(SD_ADDRESS(un), SCSI_RESET_CANCEL,
8744 8737              sd_mhd_reset_notify_cb, (caddr_t)un);
8745 8738  
8746 8739          /*
8747 8740           * protect the timeout pointers from getting nulled by
8748 8741           * their callback functions during the cancellation process.
8749 8742           * In such a scenario untimeout can be invoked with a null value.
8750 8743           */
8751 8744          _NOTE(NO_COMPETING_THREADS_NOW);
8752 8745  
↓ open down ↓ 31 lines elided ↑ open up ↑
8784 8777                   */
8785 8778                  (void) untimeout(temp_id);
8786 8779                  (void) pm_idle_component(SD_DEVINFO(un), 0);
8787 8780  
8788 8781          } else {
8789 8782                  mutex_exit(&un->un_pm_mutex);
8790 8783                  if ((un->un_f_pm_is_enabled == TRUE) &&
8791 8784                      (pm_lower_power(SD_DEVINFO(un), 0, SD_PM_STATE_STOPPED(un))
8792 8785                      != DDI_SUCCESS)) {
8793 8786                          SD_ERROR(SD_LOG_ATTACH_DETACH, un,
8794      -                    "sd_dr_detach: Lower power request failed, ignoring.\n");
     8787 +                            "%s: lower power request failed, ignoring\n",
     8788 +                            __func__);
8795 8789                          /*
8796      -                         * Fix for bug: 4297749, item # 13
8797 8790                           * The above test now includes a check to see if PM is
8798 8791                           * supported by this device before call
8799 8792                           * pm_lower_power().
8800 8793                           * Note, the following is not dead code. The call to
8801 8794                           * pm_lower_power above will generate a call back into
8802 8795                           * our sdpower routine which might result in a timeout
8803 8796                           * handler getting activated. Therefore the following
8804 8797                           * code is valid and necessary.
8805 8798                           */
8806 8799                          mutex_enter(&un->un_pm_mutex);
↓ open down ↓ 42 lines elided ↑ open up ↑
8849 8842                  if ((un->un_insert_event != NULL) &&
8850 8843                      (ddi_remove_event_handler(un->un_insert_cb_id) !=
8851 8844                      DDI_SUCCESS)) {
8852 8845                          /*
8853 8846                           * Note: We are returning here after having done
8854 8847                           * substantial cleanup above. This is consistent
8855 8848                           * with the legacy implementation but this may not
8856 8849                           * be the right thing to do.
8857 8850                           */
8858 8851                          SD_ERROR(SD_LOG_ATTACH_DETACH, un,
8859      -                            "sd_dr_detach: Cannot cancel insert event\n");
     8852 +                            "%s: cannot cancel insert event\n", __func__);
8860 8853                          goto err_remove_event;
8861 8854                  }
8862 8855                  un->un_insert_event = NULL;
8863 8856  
8864 8857                  if ((un->un_remove_event != NULL) &&
8865 8858                      (ddi_remove_event_handler(un->un_remove_cb_id) !=
8866 8859                      DDI_SUCCESS)) {
8867 8860                          /*
8868 8861                           * Note: We are returning here after having done
8869 8862                           * substantial cleanup above. This is consistent
8870 8863                           * with the legacy implementation but this may not
8871 8864                           * be the right thing to do.
8872 8865                           */
8873 8866                          SD_ERROR(SD_LOG_ATTACH_DETACH, un,
8874      -                            "sd_dr_detach: Cannot cancel remove event\n");
     8867 +                            "%s: cannot cancel remove event\n", __func__);
8875 8868                          goto err_remove_event;
8876 8869                  }
8877 8870                  un->un_remove_event = NULL;
8878 8871          }
8879 8872  
8880 8873          /* Do not free the softstate if the callback routine is active */
8881 8874          sd_sync_with_callback(un);
8882 8875  
8883 8876          cmlb_detach(un->un_cmlbhandle, (void *)SD_PATH_DIRECT);
8884 8877          cmlb_free_handle(&un->un_cmlbhandle);
↓ open down ↓ 122 lines elided ↑ open up ↑
9007 9000          mutex_exit(SD_MUTEX(un));
9008 9001  
9009 9002  err_stillbusy:
9010 9003          _NOTE(NO_COMPETING_THREADS_NOW);
9011 9004  
9012 9005  err_remove_event:
9013 9006          mutex_enter(&sd_detach_mutex);
9014 9007          un->un_detach_count--;
9015 9008          mutex_exit(&sd_detach_mutex);
9016 9009  
9017      -        SD_TRACE(SD_LOG_ATTACH_DETACH, un, "sd_unit_detach: exit failure\n");
     9010 +        SD_TRACE(SD_LOG_ATTACH_DETACH, un, "%s: exit failure\n", __func__);
9018 9011          return (DDI_FAILURE);
9019 9012  }
9020 9013  
9021 9014  
9022 9015  /*
9023 9016   *    Function: sd_create_errstats
9024 9017   *
9025 9018   * Description: This routine instantiates the device error stats.
9026 9019   *
9027 9020   *              Note: During attach the stats are instantiated first so they are
↓ open down ↓ 22768 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX