nvme/identify: simpify buffer allocation

After the NVMe library API change to perform user copies, we don't need
to pass rte_malloc() memory to the NVMe controller utility functions
like spdk_nvme_ctrlr_cmd_get_log_page().

Use regular global variables to simplify the identify example code.

At the same time, fix the code that retrieves error log pages -
previously, it was allocating space for multiple error log entries, but
it was only passing the size of a single entry to the Get Log Page
command.  Now we preallocate the worst-case array size: ELPE, which
indicates the maximum number of error log page entries, is a single
byte, and it is 0's based, so the largest possible array is just 256
entries.

Change-Id: Ia3b3b85e33bb5482df9d366803fc6e6807bf5d88
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2016-09-12 14:39:19 -07:00
parent 5e9d859327
commit 03cbd9aa72

View File

@ -35,7 +35,6 @@
#include <unistd.h>
#include <rte_config.h>
#include <rte_malloc.h>
#include <rte_mempool.h>
#include <rte_lcore.h>
@ -55,15 +54,15 @@ struct feature {
static struct feature features[256];
static struct spdk_nvme_error_information_entry *error_page = NULL;
static struct spdk_nvme_error_information_entry error_page[256];
static struct spdk_nvme_health_information_page *health_page = NULL;
static struct spdk_nvme_health_information_page health_page;
static struct spdk_nvme_intel_smart_information_page *intel_smart_page = NULL;
static struct spdk_nvme_intel_smart_information_page intel_smart_page;
static struct spdk_nvme_intel_temperature_page *intel_temperature_page = NULL;
static struct spdk_nvme_intel_temperature_page intel_temperature_page;
static struct spdk_nvme_intel_marketing_description_page *intel_md_page = NULL;
static struct spdk_nvme_intel_marketing_description_page intel_md_page;
static bool g_hex_dump = false;
@ -182,16 +181,10 @@ get_error_log_page(struct spdk_nvme_ctrlr *ctrlr)
cdata = spdk_nvme_ctrlr_get_data(ctrlr);
if (error_page == NULL) {
error_page = rte_calloc("nvme error", cdata->elpe + 1, sizeof(*error_page), 4096);
}
if (error_page == NULL) {
printf("Allocation error (error page)\n");
exit(1);
}
if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_ERROR,
SPDK_NVME_GLOBAL_NS_TAG, error_page, sizeof(*error_page), get_log_page_completion, NULL)) {
SPDK_NVME_GLOBAL_NS_TAG, error_page,
sizeof(*error_page) * (cdata->elpe + 1),
get_log_page_completion, NULL)) {
printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
exit(1);
}
@ -202,16 +195,8 @@ get_error_log_page(struct spdk_nvme_ctrlr *ctrlr)
static int
get_health_log_page(struct spdk_nvme_ctrlr *ctrlr)
{
if (health_page == NULL) {
health_page = rte_zmalloc("nvme health", sizeof(*health_page), 4096);
}
if (health_page == NULL) {
printf("Allocation error (health page)\n");
exit(1);
}
if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_HEALTH_INFORMATION,
SPDK_NVME_GLOBAL_NS_TAG, health_page, sizeof(*health_page), get_log_page_completion, NULL)) {
SPDK_NVME_GLOBAL_NS_TAG, &health_page, sizeof(health_page), get_log_page_completion, NULL)) {
printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
exit(1);
}
@ -222,16 +207,8 @@ get_health_log_page(struct spdk_nvme_ctrlr *ctrlr)
static int
get_intel_smart_log_page(struct spdk_nvme_ctrlr *ctrlr)
{
if (intel_smart_page == NULL) {
intel_smart_page = rte_zmalloc("nvme intel smart", sizeof(*intel_smart_page), 4096);
}
if (intel_smart_page == NULL) {
printf("Allocation error (intel smart page)\n");
exit(1);
}
if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_LOG_SMART, SPDK_NVME_GLOBAL_NS_TAG,
intel_smart_page, sizeof(*intel_smart_page), get_log_page_completion, NULL)) {
&intel_smart_page, sizeof(intel_smart_page), get_log_page_completion, NULL)) {
printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
exit(1);
}
@ -242,17 +219,8 @@ get_intel_smart_log_page(struct spdk_nvme_ctrlr *ctrlr)
static int
get_intel_temperature_log_page(struct spdk_nvme_ctrlr *ctrlr)
{
if (intel_temperature_page == NULL) {
intel_temperature_page = rte_zmalloc("nvme intel temperature", sizeof(*intel_temperature_page),
4096);
}
if (intel_temperature_page == NULL) {
printf("Allocation error (nvme intel temperature page)\n");
exit(1);
}
if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_LOG_TEMPERATURE,
SPDK_NVME_GLOBAL_NS_TAG, intel_temperature_page, sizeof(*intel_temperature_page),
SPDK_NVME_GLOBAL_NS_TAG, &intel_temperature_page, sizeof(intel_temperature_page),
get_log_page_completion, NULL)) {
printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
exit(1);
@ -263,17 +231,8 @@ get_intel_temperature_log_page(struct spdk_nvme_ctrlr *ctrlr)
static int
get_intel_md_log_page(struct spdk_nvme_ctrlr *ctrlr)
{
if (intel_md_page == NULL) {
intel_md_page = rte_zmalloc("nvme intel marketing description", 4096,
4096);
}
if (intel_md_page == NULL) {
printf("Allocation error (nvme intel marketing description page)\n");
exit(1);
}
if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_MARKETING_DESCRIPTION,
SPDK_NVME_GLOBAL_NS_TAG, intel_md_page, sizeof(*intel_md_page),
SPDK_NVME_GLOBAL_NS_TAG, &intel_md_page, sizeof(intel_md_page),
get_log_page_completion, NULL)) {
printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
exit(1);
@ -330,31 +289,6 @@ get_log_pages(struct spdk_nvme_ctrlr *ctrlr)
}
}
static void
cleanup(void)
{
if (error_page) {
rte_free(error_page);
error_page = NULL;
}
if (health_page) {
rte_free(health_page);
health_page = NULL;
}
if (intel_smart_page) {
rte_free(intel_smart_page);
intel_smart_page = NULL;
}
if (intel_temperature_page) {
rte_free(intel_temperature_page);
intel_temperature_page = NULL;
}
if (intel_md_page) {
rte_free(intel_md_page);
intel_md_page = NULL;
}
}
static void
print_uint128_hex(uint64_t *v)
{
@ -679,216 +613,216 @@ print_controller(struct spdk_nvme_ctrlr *ctrlr, struct spdk_pci_device *pci_dev)
printf("\n");
}
if (features[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD].valid && health_page) {
if (features[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD].valid) {
printf("Health Information\n");
printf("==================\n");
if (g_hex_dump) {
hex_dump(health_page, sizeof(*health_page));
hex_dump(&health_page, sizeof(health_page));
printf("\n");
}
printf("Critical Warnings:\n");
printf(" Available Spare Space: %s\n",
health_page->critical_warning.bits.available_spare ? "WARNING" : "OK");
health_page.critical_warning.bits.available_spare ? "WARNING" : "OK");
printf(" Temperature: %s\n",
health_page->critical_warning.bits.temperature ? "WARNING" : "OK");
health_page.critical_warning.bits.temperature ? "WARNING" : "OK");
printf(" Device Reliability: %s\n",
health_page->critical_warning.bits.device_reliability ? "WARNING" : "OK");
health_page.critical_warning.bits.device_reliability ? "WARNING" : "OK");
printf(" Read Only: %s\n",
health_page->critical_warning.bits.read_only ? "Yes" : "No");
health_page.critical_warning.bits.read_only ? "Yes" : "No");
printf(" Volatile Memory Backup: %s\n",
health_page->critical_warning.bits.volatile_memory_backup ? "WARNING" : "OK");
health_page.critical_warning.bits.volatile_memory_backup ? "WARNING" : "OK");
printf("Current Temperature: %u Kelvin (%u Celsius)\n",
health_page->temperature,
health_page->temperature - 273);
health_page.temperature,
health_page.temperature - 273);
printf("Temperature Threshold: %u Kelvin (%u Celsius)\n",
features[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD].result,
features[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD].result - 273);
printf("Available Spare: %u%%\n", health_page->available_spare);
printf("Life Percentage Used: %u%%\n", health_page->percentage_used);
printf("Available Spare: %u%%\n", health_page.available_spare);
printf("Life Percentage Used: %u%%\n", health_page.percentage_used);
printf("Data Units Read: ");
print_uint128_dec(health_page->data_units_read);
print_uint128_dec(health_page.data_units_read);
printf("\n");
printf("Data Units Written: ");
print_uint128_dec(health_page->data_units_written);
print_uint128_dec(health_page.data_units_written);
printf("\n");
printf("Host Read Commands: ");
print_uint128_dec(health_page->host_read_commands);
print_uint128_dec(health_page.host_read_commands);
printf("\n");
printf("Host Write Commands: ");
print_uint128_dec(health_page->host_write_commands);
print_uint128_dec(health_page.host_write_commands);
printf("\n");
printf("Controller Busy Time: ");
print_uint128_dec(health_page->controller_busy_time);
print_uint128_dec(health_page.controller_busy_time);
printf(" minutes\n");
printf("Power Cycles: ");
print_uint128_dec(health_page->power_cycles);
print_uint128_dec(health_page.power_cycles);
printf("\n");
printf("Power On Hours: ");
print_uint128_dec(health_page->power_on_hours);
print_uint128_dec(health_page.power_on_hours);
printf(" hours\n");
printf("Unsafe Shutdowns: ");
print_uint128_dec(health_page->unsafe_shutdowns);
print_uint128_dec(health_page.unsafe_shutdowns);
printf("\n");
printf("Unrecoverable Media Errors: ");
print_uint128_dec(health_page->media_errors);
print_uint128_dec(health_page.media_errors);
printf("\n");
printf("Lifetime Error Log Entries: ");
print_uint128_dec(health_page->num_error_info_log_entries);
print_uint128_dec(health_page.num_error_info_log_entries);
printf("\n");
printf("\n");
}
if (intel_smart_page) {
if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_LOG_SMART)) {
size_t i = 0;
printf("Intel Health Information\n");
printf("==================\n");
for (i = 0;
i < sizeof(intel_smart_page->attributes) / sizeof(intel_smart_page->attributes[0]); i++) {
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_PROGRAM_FAIL_COUNT) {
i < sizeof(intel_smart_page.attributes) / sizeof(intel_smart_page.attributes[0]); i++) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_PROGRAM_FAIL_COUNT) {
printf("Program Fail Count:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_ERASE_FAIL_COUNT) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_ERASE_FAIL_COUNT) {
printf("Erase Fail Count:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_WEAR_LEVELING_COUNT) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_WEAR_LEVELING_COUNT) {
printf("Wear Leveling Count:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: \n");
printf(" Min: ");
print_uint_var_dec(&intel_smart_page->attributes[i].raw_value[0], 2);
print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[0], 2);
printf("\n");
printf(" Max: ");
print_uint_var_dec(&intel_smart_page->attributes[i].raw_value[2], 2);
print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[2], 2);
printf("\n");
printf(" Avg: ");
print_uint_var_dec(&intel_smart_page->attributes[i].raw_value[4], 2);
print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[4], 2);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_E2E_ERROR_COUNT) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_E2E_ERROR_COUNT) {
printf("End to End Error Detection Count:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_CRC_ERROR_COUNT) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_CRC_ERROR_COUNT) {
printf("CRC Error Count:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_MEDIA_WEAR) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_MEDIA_WEAR) {
printf("Timed Workload, Media Wear:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_HOST_READ_PERCENTAGE) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_HOST_READ_PERCENTAGE) {
printf("Timed Workload, Host Read/Write Ratio:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("%%");
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_TIMER) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_TIMER) {
printf("Timed Workload, Timer:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS) {
printf("Thermal Throttle Status:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: \n");
printf(" Percentage: %d%%\n", intel_smart_page->attributes[i].raw_value[0]);
printf(" Percentage: %d%%\n", intel_smart_page.attributes[i].raw_value[0]);
printf(" Throttling Event Count: ");
print_uint_var_dec(&intel_smart_page->attributes[i].raw_value[1], 4);
print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[1], 4);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER) {
printf("Retry Buffer Overflow Counter:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT) {
printf("PLL Lock Loss Count:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_NAND_BYTES_WRITTEN) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_NAND_BYTES_WRITTEN) {
printf("NAND Bytes Written:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
if (intel_smart_page->attributes[i].code == SPDK_NVME_INTEL_SMART_HOST_BYTES_WRITTEN) {
if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_HOST_BYTES_WRITTEN) {
printf("Host Bytes Written:\n");
printf(" Normalized Value : %d\n",
intel_smart_page->attributes[i].normalized_value);
intel_smart_page.attributes[i].normalized_value);
printf(" Current Raw Value: ");
print_uint_var_dec(intel_smart_page->attributes[i].raw_value, 6);
print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
printf("\n");
}
}
printf("\n");
}
if (intel_temperature_page) {
if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_LOG_TEMPERATURE)) {
printf("Intel Temperature Information\n");
printf("==================\n");
printf("Current Temperature: %lu\n", intel_temperature_page->current_temperature);
printf("Current Temperature: %lu\n", intel_temperature_page.current_temperature);
printf("Overtemp shutdown Flag for last critical component temperature: %lu\n",
intel_temperature_page->shutdown_flag_last);
intel_temperature_page.shutdown_flag_last);
printf("Overtemp shutdown Flag for life critical component temperature: %lu\n",
intel_temperature_page->shutdown_flag_life);
printf("Highest temperature: %lu\n", intel_temperature_page->highest_temperature);
printf("Lowest temperature: %lu\n", intel_temperature_page->lowest_temperature);
intel_temperature_page.shutdown_flag_life);
printf("Highest temperature: %lu\n", intel_temperature_page.highest_temperature);
printf("Lowest temperature: %lu\n", intel_temperature_page.lowest_temperature);
printf("Specified Maximum Operating Temperature: %lu\n",
intel_temperature_page->specified_max_op_temperature);
intel_temperature_page.specified_max_op_temperature);
printf("Specified Minimum Operating Temperature: %lu\n",
intel_temperature_page->specified_min_op_temperature);
printf("Estimated offset: %ld\n", intel_temperature_page->estimated_offset);
intel_temperature_page.specified_min_op_temperature);
printf("Estimated offset: %ld\n", intel_temperature_page.estimated_offset);
printf("\n");
printf("\n");
}
if (intel_md_page) {
if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_MARKETING_DESCRIPTION)) {
printf("Intel Marketing Information\n");
printf("==================\n");
snprintf(str, sizeof(intel_md_page->marketing_product), "%s", intel_md_page->marketing_product);
snprintf(str, sizeof(intel_md_page.marketing_product), "%s", intel_md_page.marketing_product);
printf("Marketing Product Information: %s\n", str);
printf("\n");
printf("\n");
@ -994,7 +928,5 @@ int main(int argc, char **argv)
rc = 1;
}
cleanup();
return rc;
}