Author: scottl
Date: Tue Jul 19 03:13:51 2016
New Revision: 303017
URL: https://svnweb.freebsd.org/changeset/base/303017

Log:
  Implement crashdump support on NVME
  
  MFC after:    3 days
  Sponsored by: Netflix, Inc.

Modified:
  head/sys/dev/nvd/nvd.c
  head/sys/dev/nvme/nvme.h
  head/sys/dev/nvme/nvme_ns_cmd.c

Modified: head/sys/dev/nvd/nvd.c
==============================================================================
--- head/sys/dev/nvd/nvd.c      Tue Jul 19 00:47:00 2016        (r303016)
+++ head/sys/dev/nvd/nvd.c      Tue Jul 19 03:13:51 2016        (r303017)
@@ -47,6 +47,7 @@ struct nvd_disk;
 
 static disk_ioctl_t nvd_ioctl;
 static disk_strategy_t nvd_strategy;
+static dumper_t nvd_dump;
 
 static void nvd_done(void *arg, const struct nvme_completion *cpl);
 
@@ -226,6 +227,26 @@ nvd_ioctl(struct disk *ndisk, u_long cmd
        return (ret);
 }
 
+static int
+nvd_dump(void *arg, void *virt, vm_offset_t phys, off_t offset, size_t len)
+{
+       struct nvd_disk *ndisk;
+       struct disk *dp;
+       int error;
+
+       dp = arg;
+       ndisk = dp->d_drv1;
+
+       if (len > 0) {
+               if ((error = nvme_ns_dump(ndisk->ns, virt, offset, len)) != 0)
+                       return (error);
+       } else {
+               /* XXX sync to stable storage */
+       }
+
+       return (0);
+}
+
 static void
 nvd_done(void *arg, const struct nvme_completion *cpl)
 {
@@ -302,6 +323,7 @@ nvd_new_disk(struct nvme_namespace *ns, 
        disk = disk_alloc();
        disk->d_strategy = nvd_strategy;
        disk->d_ioctl = nvd_ioctl;
+       disk->d_dump = nvd_dump;
        disk->d_name = NVD_STR;
        disk->d_drv1 = ndisk;
 

Modified: head/sys/dev/nvme/nvme.h
==============================================================================
--- head/sys/dev/nvme/nvme.h    Tue Jul 19 00:47:00 2016        (r303016)
+++ head/sys/dev/nvme/nvme.h    Tue Jul 19 03:13:51 2016        (r303017)
@@ -876,6 +876,8 @@ int nvme_ns_cmd_deallocate(struct nvme_n
                               void *cb_arg);
 int    nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
                          void *cb_arg);
+int    nvme_ns_dump(struct nvme_namespace *ns, void *virt, off_t offset,
+                    size_t len);
 
 /* Registration functions */
 struct nvme_consumer * nvme_register_consumer(nvme_cons_ns_fn_t    ns_fn,

Modified: head/sys/dev/nvme/nvme_ns_cmd.c
==============================================================================
--- head/sys/dev/nvme/nvme_ns_cmd.c     Tue Jul 19 00:47:00 2016        
(r303016)
+++ head/sys/dev/nvme/nvme_ns_cmd.c     Tue Jul 19 03:13:51 2016        
(r303017)
@@ -151,3 +151,47 @@ nvme_ns_cmd_flush(struct nvme_namespace 
 
        return (0);
 }
+
+/* Timeout = 1 sec */
+#define NVD_DUMP_TIMEOUT       100000
+
+int
+nvme_ns_dump(struct nvme_namespace *ns, void *virt, off_t offset, size_t len)
+{
+       struct nvme_completion_poll_status status;
+       struct nvme_request *req;
+       struct nvme_command *cmd;
+       uint64_t lba, lba_count;
+       int i;
+
+       status.done = FALSE;
+       req = nvme_allocate_request_vaddr(virt, len, nvme_completion_poll_cb,
+           &status);
+       if (req == NULL)
+               return (ENOMEM);
+
+       cmd = &req->cmd;
+       cmd->opc = NVME_OPC_WRITE;
+       cmd->nsid = ns->id;
+
+       lba = offset / nvme_ns_get_sector_size(ns);
+       lba_count = len / nvme_ns_get_sector_size(ns);
+
+       *(uint64_t *)&cmd->cdw10 = lba;
+       cmd->cdw12 = lba_count - 1;
+
+       nvme_ctrlr_submit_io_request(ns->ctrlr, req);
+       if (req->qpair == NULL)
+               return (ENXIO);
+
+       i = 0;
+       while ((i++ < NVD_DUMP_TIMEOUT) && (status.done == FALSE)) {
+               DELAY(10);
+               nvme_qpair_process_completions(req->qpair);
+       }
+
+       if (status.done == FALSE)
+               return (ETIMEDOUT);
+
+       return (0);
+}
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to