]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sparc64: add DAX2 support to dax driver
authorAllen Pais <allen.pais@oracle.com>
Thu, 22 Jun 2017 07:06:21 +0000 (12:36 +0530)
committerAllen Pais <allen.pais@oracle.com>
Sat, 24 Jun 2017 01:27:49 +0000 (06:57 +0530)
Orabug: 25904994

Introduce DAX2 support in the driver. This involves negotiating the right
version with hypervisor as well as exposing a new INIT_V2 ioctl. This new
ioctl will return failure if DAX2 is not present on the system, otherwise
it will attempt to initialize the DAX2. A user should first call INIT_V2
and on failure call INIT_V1. See Documentation/sparc/dax.txt for more
detail.

Signed-off-by: Jonathan Helman <jonathan.helman@oracle.com>
Reviewed-by: Sanath Kumar <sanath.s.kumar@oracle.com>
Signed-off-by: Allen Pais <allen.pais@oracle.com>
Documentation/sparc/dax.txt
arch/sparc/dax/dax_impl.h
arch/sparc/dax/dax_main.c
arch/sparc/dax/sys_dax.h
arch/sparc/include/asm/hypervisor.h
arch/sparc/kernel/hvapi.c

index 877d37f36c9e353e4ead3bb3e82aa6217e24c9cd..9156f9a4f77d6b46d7db46dc4e560fd050acc0f2 100644 (file)
@@ -82,6 +82,19 @@ needed for the mmap() call so that the user can get access to the completion
 area buffer. Another value returned is the maximum length of the CCB array
 that may be submitted.
 
+CCB_THR_INIT_V2
+
+Initializes the DAX driver for DAX2 if available. If DAX2 is not available,
+returns an error. The user should do the following to determine the DAX version
+on their system:
+
+if (ioctl(CCB_THR_INIT_V2) == SUCCESS)
+       /* DAX2 available on system */
+else if (ioctl(CCB_THR_INIT) == SUCCESS)
+       /* DAX1 available on system */
+else
+       /* no DAX available on system */
+
 CCB_THR_FINI
 
 Destroys a context for a thread. After doing this, the thread can no longer
index 894dfe5ea35947ec52de40ae7c4995c8c8720440..51eb93eaf61189a9190fe01840f31ee2b3c401ab 100644 (file)
@@ -108,6 +108,8 @@ extern const struct vm_operations_struct dax_vm_ops;
 #define        DAX_NAME                "dax"
 #define DAX_MINOR              1UL
 #define DAX_MAJOR              1UL
+#define DAX2_MINOR             0UL
+#define DAX2_MAJOR             2UL
 
 #define DAX1_STR    "ORCL,sun4v-dax"
 #define DAX1_FC_STR "ORCL,sun4v-dax-fc"
index 98e046a211149eeab6fc4b62f7d7b9a891e50c62..3a15be27965f93d66d24321d294c875667212bec 100644 (file)
@@ -73,7 +73,7 @@ static int hv_get_hwqueue_size(unsigned long *qsize)
 
 static int __init dax_attach(void)
 {
-       unsigned long minor = DAX_MINOR;
+       unsigned long major, minor, minor_requested;
        unsigned long max_ccbs;
        int ret = 0, found_dax = 0;
        struct mdesc_handle *hp = mdesc_grab();
@@ -106,14 +106,22 @@ static int __init dax_attach(void)
                if (!strncmp(prop, DAX1_FC_STR, strlen(DAX1_FC_STR))) {
                        msg = "dax1-flow-control";
                        dax_type = DAX1;
+                       major = DAX_MAJOR;
+                       minor_requested = DAX_MINOR;
                } else if (!strncmp(prop, DAX2_STR, strlen(DAX2_STR))) {
                        msg = "dax2";
                        dax_type = DAX2;
+                       major = DAX2_MAJOR;
+                       minor_requested = DAX2_MINOR;
                } else if (!strncmp(prop, DAX1_STR, strlen(DAX1_STR))) {
                        msg = "dax1-no-flow-control";
                        dax_no_flow_ctl = true;
                        dax_type = DAX1;
+                       major = DAX_MAJOR;
+                       minor_requested = DAX_MINOR;
                } else {
+                       major = DAX_MAJOR;
+                       minor_requested = DAX_MINOR;
                        break;
                }
                found_dax = 1;
@@ -129,21 +137,23 @@ static int __init dax_attach(void)
                }
        }
 
-       dax_dbg("Registering DAX HV api with minor %ld", minor);
-       if (sun4v_hvapi_register(HV_GRP_M7_DAX, DAX_MAJOR, &minor)) {
+       minor = minor_requested;
+       dax_dbg("Registering DAX HV api with major %ld minor %ld", major,
+               minor);
+       if (sun4v_hvapi_register(HV_GRP_DAX, major, &minor)) {
                dax_err("hvapi_register failed");
                if ((force & FORCE_LOAD_ON_ERROR) == 0) {
                        ret = -ENODEV;
                        goto done;
                }
        } else {
-               dax_dbg("Max minor supported by HV = %ld", minor);
-               minor = min(minor, DAX_MINOR);
-               dax_dbg("registered DAX major %ld minor %ld ",
-                                DAX_MAJOR, minor);
+               dax_dbg("Max minor supported by HV = %ld (major %ld)", minor,
+                       major);
+               minor = min(minor, minor_requested);
+               dax_dbg("registered DAX major %ld minor %ld", major, minor);
        }
 
-       dax_no_ra_pgsz = (DAX_MAJOR == 1) && (minor == 0) && !dax_has_ra_pgsz();
+       dax_no_ra_pgsz = (major == 1) && (minor == 0) && !dax_has_ra_pgsz();
        dax_dbg("RA pagesize feature %spresent", dax_no_ra_pgsz ? "not " : "");
 
        ret = hv_get_hwqueue_size(&max_ccbs);
@@ -287,6 +297,13 @@ static long dax_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
 {
        dax_dbg("cmd=0x%x, f=%p, priv=%p",  cmd, f, f->private_data);
        switch (cmd) {
+       case DAXIOC_CCB_THR_INIT_V2:
+               if (dax_type != DAX2)
+                       return -ENXIO;
+               /*
+                * fall-through: INIT_V2 is just to test if DAX2 is available,
+                * but initializing DAX1 and DAX2 is the same
+                */
        case DAXIOC_CCB_THR_INIT:
                return dax_ioctl_ccb_thr_init((void *)arg, f);
        case DAXIOC_CCB_THR_FINI:
index fb0a985237c8959a0a214f9f10fcf2df74e4892f..40b00843f9a60c5f24a9d73251d6b02de9c052b9 100644 (file)
@@ -56,6 +56,7 @@
 
 /* CCB thread initialization */
 #define        DAXIOC_CCB_THR_INIT     _IOWR(DAXIOC, 6, struct dax_ccb_thr_init_arg)
+#define        DAXIOC_CCB_THR_INIT_V2  _IOWR(DAXIOC, 11, struct dax_ccb_thr_init_arg)
 /* free CCB thread resources */
 #define        DAXIOC_CCB_THR_FINI     _IO(DAXIOC,   2)
 /* CCB CA dequeue */
@@ -78,7 +79,7 @@
 #define DAXIOC_PERF_CLEAR_COUNTERS     _IOW(DAXIOC, 0xBC, void *)
 
 /*
- * DAXIOC_CCB_THR_INIT
+ * DAXIOC_CCB_THR_INIT, DAXIOC_CCB_THR_INIT_V2
  * dcti_ccb_buf_maxlen - return u32 length
  * dcti_compl_maplen - return u64 mmap length
  * dcti_compl_mapoff - return u64 mmap offset
index 86e357d18f10609a51d8f5956b217ee2450256b6..b0bbdd6f5954c76dd81e3086460f1d0b13beffaf 100644 (file)
@@ -998,6 +998,7 @@ unsigned long sun4v_dax_ccb_submit(void *ccb, int len, long flags,
 #define HV_DAX_CCB_VA_SECONDARY                BIT_FIELD(2UL, 12)
 #define HV_DAX_CCB_VA_NUCLEUS          BIT_FIELD(3UL, 12)
 #define HV_DAX_CCB_VA_PRIVILEGED       BIT(14)
+#define HV_DAX_VA_READ_ADI_DISABLE     BIT(15) /* defined in API 2.0 */
 
 /* dax_ccb_info()
  * TRAP:       HV_FAST_TRAP
@@ -3823,7 +3824,7 @@ struct hv_pci_priq_intx_info {
 #define HV_GRP_SDIO                    0x0108
 #define HV_GRP_SDIO_ERR                        0x0109
 #define HV_GRP_REBOOT_DATA             0x0110
-#define HV_GRP_M7_DAX                  0x0113
+#define HV_GRP_DAX                     0x0113
 #define HV_GRP_M7_PERF                 0x0114
 #define        HV_GRP_PRIQ                     0x011b
 #define        HV_GRP_PRIQ_PCI                 0x011c
index 19b3ca1cddfd12b74b077d94ea2308e7ec96c5d8..7a873ba5103a2fb29dbb8c56e1bf5998b2eaf95b 100644 (file)
@@ -39,7 +39,7 @@ static struct api_info api_table[] = {
        { .group = HV_GRP_SDIO,                                 },
        { .group = HV_GRP_SDIO_ERR,                             },
        { .group = HV_GRP_REBOOT_DATA,                          },
-       { .group = HV_GRP_M7_DAX,                               },
+       { .group = HV_GRP_DAX,                                  },
        { .group = HV_GRP_PRIQ,                                 },
        { .group = HV_GRP_PRIQ_PCI,                             },
        { .group = HV_GRP_NIAG_PERF,    .flags = FLAG_PRE_API   },