Print this page
7448 nvme: performance regression when volatile write cache not present
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>


2490 }
2491 
2492 static int
2493 nvme_fm_errcb(dev_info_t *dip, ddi_fm_error_t *fm_error, const void *arg)
2494 {
2495         _NOTE(ARGUNUSED(arg));
2496 
2497         pci_ereport_post(dip, fm_error, NULL);
2498         return (fm_error->fme_status);
2499 }
2500 
2501 static int
2502 nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2503 {
2504         nvme_t *nvme;
2505         int instance;
2506         int nregs;
2507         off_t regsize;
2508         int i;
2509         char name[32];

2510 
2511         if (cmd != DDI_ATTACH)
2512                 return (DDI_FAILURE);
2513 
2514         instance = ddi_get_instance(dip);
2515 
2516         if (ddi_soft_state_zalloc(nvme_state, instance) != DDI_SUCCESS)
2517                 return (DDI_FAILURE);
2518 
2519         nvme = ddi_get_soft_state(nvme_state, instance);
2520         ddi_set_driver_private(dip, nvme);
2521         nvme->n_dip = dip;
2522 
2523         nvme->n_strict_version = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2524             DDI_PROP_DONTPASS, "strict-version", 1) == 1 ? B_TRUE : B_FALSE;
2525         nvme->n_ignore_unknown_vendor_status = ddi_prop_get_int(DDI_DEV_T_ANY,
2526             dip, DDI_PROP_DONTPASS, "ignore-unknown-vendor-status", 0) == 1 ?
2527             B_TRUE : B_FALSE;
2528         nvme->n_admin_queue_len = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2529             DDI_PROP_DONTPASS, "admin-queue-len", NVME_DEFAULT_ADMIN_QUEUE_LEN);


2626 
2627         /*
2628          * Create PRP DMA cache
2629          */
2630         (void) snprintf(name, sizeof (name), "%s%d_prp_cache",
2631             ddi_driver_name(dip), ddi_get_instance(dip));
2632         nvme->n_prp_cache = kmem_cache_create(name, sizeof (nvme_dma_t),
2633             0, nvme_prp_dma_constructor, nvme_prp_dma_destructor,
2634             NULL, (void *)nvme, NULL, 0);
2635 
2636         if (nvme_init(nvme) != DDI_SUCCESS)
2637                 goto fail;
2638 
2639         /*
2640          * Attach the blkdev driver for each namespace.
2641          */
2642         for (i = 0; i != nvme->n_namespace_count; i++) {
2643                 if (nvme->n_ns[i].ns_ignore)
2644                         continue;
2645 




2646                 nvme->n_ns[i].ns_bd_hdl = bd_alloc_handle(&nvme->n_ns[i],
2647                     &nvme_bd_ops, &nvme->n_prp_dma_attr, KM_SLEEP);
2648 
2649                 if (nvme->n_ns[i].ns_bd_hdl == NULL) {
2650                         dev_err(dip, CE_WARN,
2651                             "!failed to get blkdev handle for namespace %d", i);
2652                         goto fail;
2653                 }
2654 
2655                 if (bd_attach_handle(dip, nvme->n_ns[i].ns_bd_hdl)
2656                     != DDI_SUCCESS) {
2657                         dev_err(dip, CE_WARN,
2658                             "!failed to attach blkdev handle for namespace %d",
2659                             i);
2660                         goto fail;
2661                 }
2662         }
2663 
2664         return (DDI_SUCCESS);
2665 
2666 fail:
2667         /* attach successful anyway so that FMA can retire the device */




2490 }
2491 
2492 static int
2493 nvme_fm_errcb(dev_info_t *dip, ddi_fm_error_t *fm_error, const void *arg)
2494 {
2495         _NOTE(ARGUNUSED(arg));
2496 
2497         pci_ereport_post(dip, fm_error, NULL);
2498         return (fm_error->fme_status);
2499 }
2500 
2501 static int
2502 nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2503 {
2504         nvme_t *nvme;
2505         int instance;
2506         int nregs;
2507         off_t regsize;
2508         int i;
2509         char name[32];
2510         bd_ops_t l_bd_ops = nvme_bd_ops;
2511 
2512         if (cmd != DDI_ATTACH)
2513                 return (DDI_FAILURE);
2514 
2515         instance = ddi_get_instance(dip);
2516 
2517         if (ddi_soft_state_zalloc(nvme_state, instance) != DDI_SUCCESS)
2518                 return (DDI_FAILURE);
2519 
2520         nvme = ddi_get_soft_state(nvme_state, instance);
2521         ddi_set_driver_private(dip, nvme);
2522         nvme->n_dip = dip;
2523 
2524         nvme->n_strict_version = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2525             DDI_PROP_DONTPASS, "strict-version", 1) == 1 ? B_TRUE : B_FALSE;
2526         nvme->n_ignore_unknown_vendor_status = ddi_prop_get_int(DDI_DEV_T_ANY,
2527             dip, DDI_PROP_DONTPASS, "ignore-unknown-vendor-status", 0) == 1 ?
2528             B_TRUE : B_FALSE;
2529         nvme->n_admin_queue_len = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2530             DDI_PROP_DONTPASS, "admin-queue-len", NVME_DEFAULT_ADMIN_QUEUE_LEN);


2627 
2628         /*
2629          * Create PRP DMA cache
2630          */
2631         (void) snprintf(name, sizeof (name), "%s%d_prp_cache",
2632             ddi_driver_name(dip), ddi_get_instance(dip));
2633         nvme->n_prp_cache = kmem_cache_create(name, sizeof (nvme_dma_t),
2634             0, nvme_prp_dma_constructor, nvme_prp_dma_destructor,
2635             NULL, (void *)nvme, NULL, 0);
2636 
2637         if (nvme_init(nvme) != DDI_SUCCESS)
2638                 goto fail;
2639 
2640         /*
2641          * Attach the blkdev driver for each namespace.
2642          */
2643         for (i = 0; i != nvme->n_namespace_count; i++) {
2644                 if (nvme->n_ns[i].ns_ignore)
2645                         continue;
2646 
2647                 if (!nvme->n_write_cache_present) {
2648                         l_bd_ops.o_sync_cache = NULL;
2649                 }
2650 
2651                 nvme->n_ns[i].ns_bd_hdl = bd_alloc_handle(&nvme->n_ns[i],
2652                     &l_bd_ops, &nvme->n_prp_dma_attr, KM_SLEEP);
2653 
2654                 if (nvme->n_ns[i].ns_bd_hdl == NULL) {
2655                         dev_err(dip, CE_WARN,
2656                             "!failed to get blkdev handle for namespace %d", i);
2657                         goto fail;
2658                 }
2659 
2660                 if (bd_attach_handle(dip, nvme->n_ns[i].ns_bd_hdl)
2661                     != DDI_SUCCESS) {
2662                         dev_err(dip, CE_WARN,
2663                             "!failed to attach blkdev handle for namespace %d",
2664                             i);
2665                         goto fail;
2666                 }
2667         }
2668 
2669         return (DDI_SUCCESS);
2670 
2671 fail:
2672         /* attach successful anyway so that FMA can retire the device */