Implement crashdump support on NVME
MFC after: 3 days Sponsored by: Netflix, Inc.
This commit is contained in:
parent
b1b8369114
commit
a498975ef7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=303017
@ -47,6 +47,7 @@ struct nvd_disk;
|
|||||||
|
|
||||||
static disk_ioctl_t nvd_ioctl;
|
static disk_ioctl_t nvd_ioctl;
|
||||||
static disk_strategy_t nvd_strategy;
|
static disk_strategy_t nvd_strategy;
|
||||||
|
static dumper_t nvd_dump;
|
||||||
|
|
||||||
static void nvd_done(void *arg, const struct nvme_completion *cpl);
|
static void nvd_done(void *arg, const struct nvme_completion *cpl);
|
||||||
|
|
||||||
@ -226,6 +227,26 @@ nvd_ioctl(struct disk *ndisk, u_long cmd, void *data, int fflag,
|
|||||||
return (ret);
|
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
|
static void
|
||||||
nvd_done(void *arg, const struct nvme_completion *cpl)
|
nvd_done(void *arg, const struct nvme_completion *cpl)
|
||||||
{
|
{
|
||||||
@ -302,6 +323,7 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg)
|
|||||||
disk = disk_alloc();
|
disk = disk_alloc();
|
||||||
disk->d_strategy = nvd_strategy;
|
disk->d_strategy = nvd_strategy;
|
||||||
disk->d_ioctl = nvd_ioctl;
|
disk->d_ioctl = nvd_ioctl;
|
||||||
|
disk->d_dump = nvd_dump;
|
||||||
disk->d_name = NVD_STR;
|
disk->d_name = NVD_STR;
|
||||||
disk->d_drv1 = ndisk;
|
disk->d_drv1 = ndisk;
|
||||||
|
|
||||||
|
@ -876,6 +876,8 @@ int nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
|
|||||||
void *cb_arg);
|
void *cb_arg);
|
||||||
int nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
|
int nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
|
||||||
void *cb_arg);
|
void *cb_arg);
|
||||||
|
int nvme_ns_dump(struct nvme_namespace *ns, void *virt, off_t offset,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
/* Registration functions */
|
/* Registration functions */
|
||||||
struct nvme_consumer * nvme_register_consumer(nvme_cons_ns_fn_t ns_fn,
|
struct nvme_consumer * nvme_register_consumer(nvme_cons_ns_fn_t ns_fn,
|
||||||
|
@ -151,3 +151,47 @@ nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn, void *cb_arg)
|
|||||||
|
|
||||||
return (0);
|
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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user