scsi: mpt3sas: Add app owned flag support for diag buffer
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>
Fri, 13 Sep 2019 13:04:45 +0000 (09:04 -0400)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 1 Oct 2019 02:32:47 +0000 (22:32 -0400)
Added a new status flag named MPT3_DIAG_BUFFER_IS_APP_OWNED and it will set
whenever application registers the diag buffer & it will be cleared when
application unregisters the buffer.

When this flag is enabled, and if application issues diag buffer register
command without releasing the buffer, then register command will be failed
with -EINVAL status by saying that this buffer is already registered by the
application.

When user issues a trace buffer register command through sysfs parameter,
and if trace buffer is in released stated but not yet unregistered by the
application which was owning it, then driver will unregister the buffer by
itself and freshly register the 1MB sized trace buffer with the HBA
firmware.

Link: https://lore.kernel.org/r/1568379890-18347-9-git-send-email-sreekanth.reddy@broadcom.com
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpt3sas/mpt3sas_base.h
drivers/scsi/mpt3sas/mpt3sas_ctl.c

index eaeb71f9b546f976da2757c2af22218d0d002046..91f663688bf0635eaa2b304735ce2a464c66de19 100644 (file)
@@ -304,6 +304,7 @@ struct mpt3sas_nvme_cmd {
 #define MPT3_DIAG_BUFFER_IS_RELEASED   (0x02)
 #define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04)
 #define MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED (0x08)
+#define MPT3_DIAG_BUFFER_IS_APP_OWNED (0x10)
 
 /*
  * HP HBA branding
index b5492f1a73a0e6c8105b8077517fd9ce85370b69..62e878d6a52b5a9731dc37a4b5f9c94cb0574ff8 100644 (file)
@@ -1565,6 +1565,16 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
                return -EINVAL;
        }
 
+       if ((ioc->diag_buffer_status[buffer_type] &
+           MPT3_DIAG_BUFFER_IS_APP_OWNED) &&
+           !(ioc->diag_buffer_status[buffer_type] &
+           MPT3_DIAG_BUFFER_IS_RELEASED)) {
+               ioc_err(ioc,
+                   "%s: buffer_type(0x%02x) is already registered by application with UID(0x%08x)\n",
+                   __func__, buffer_type, ioc->unique_id[buffer_type]);
+               return -EINVAL;
+       }
+
        if (ioc->diag_buffer_status[buffer_type] &
            MPT3_DIAG_BUFFER_IS_REGISTERED) {
                /*
@@ -1884,6 +1894,12 @@ _ctl_diag_register(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
        }
 
        rc = _ctl_diag_register_2(ioc, &karg);
+
+       if (!rc && (ioc->diag_buffer_status[karg.buffer_type] &
+           MPT3_DIAG_BUFFER_IS_REGISTERED))
+               ioc->diag_buffer_status[karg.buffer_type] |=
+                   MPT3_DIAG_BUFFER_IS_APP_OWNED;
+
        return rc;
 }
 
@@ -1955,6 +1971,8 @@ _ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
        if (ioc->diag_buffer_status[buffer_type] &
            MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) {
                ioc->unique_id[buffer_type] = MPT3DIAGBUFFUNIQUEID;
+               ioc->diag_buffer_status[buffer_type] &=
+                   ~MPT3_DIAG_BUFFER_IS_APP_OWNED;
                ioc->diag_buffer_status[buffer_type] &=
                    ~MPT3_DIAG_BUFFER_IS_REGISTERED;
        } else {
@@ -2040,6 +2058,10 @@ _ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
            MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED))
                karg.application_flags |= MPT3_APP_FLAGS_DYNAMIC_BUFFER_ALLOC;
 
+       if ((ioc->diag_buffer_status[buffer_type] &
+           MPT3_DIAG_BUFFER_IS_APP_OWNED))
+               karg.application_flags |= MPT3_APP_FLAGS_APP_OWNED;
+
        for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++)
                karg.product_specific[i] =
                    ioc->product_specific[buffer_type][i];
@@ -3331,8 +3353,27 @@ host_trace_buffer_enable_store(struct device *cdev,
                        /* post the same buffer allocated previously */
                        diag_register.requested_buffer_size =
                            ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE];
-               } else
+               } else {
+                       /*
+                        * Free the diag buffer memory which was previously
+                        * allocated by an application.
+                        */
+                       if ((ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE] != 0)
+                           &&
+                           (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
+                           MPT3_DIAG_BUFFER_IS_APP_OWNED)) {
+                               pci_free_consistent(ioc->pdev,
+                                   ioc->diag_buffer_sz[
+                                   MPI2_DIAG_BUF_TYPE_TRACE],
+                                   ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE],
+                                   ioc->diag_buffer_dma[
+                                   MPI2_DIAG_BUF_TYPE_TRACE]);
+                               ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE] =
+                                   NULL;
+                       }
+
                        diag_register.requested_buffer_size = (1024 * 1024);
+               }
 
                diag_register.unique_id =
                    (ioc->hba_mpi_version_belonged == MPI2_VERSION) ?