Commit 0caff003 authored by Asai Thambi S P's avatar Asai Thambi S P Committed by Jens Axboe

mtip32xx: Add debugfs entry device_status

This patch adds a new debugfs entry 'device_status' in
/sys/kernel/debug/rssd. The value of this entry shows
devices online and those in the process of removing.
Signed-off-by: default avatarSam Bradshaw <sbradshaw@micron.com>
Signed-off-by: default avatarAsai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 6b06d35f
...@@ -81,12 +81,17 @@ ...@@ -81,12 +81,17 @@
/* Device instance number, incremented each time a device is probed. */ /* Device instance number, incremented each time a device is probed. */
static int instance; static int instance;
struct list_head online_list;
struct list_head removing_list;
spinlock_t dev_lock;
/* /*
* Global variable used to hold the major block device number * Global variable used to hold the major block device number
* allocated in mtip_init(). * allocated in mtip_init().
*/ */
static int mtip_major; static int mtip_major;
static struct dentry *dfs_parent; static struct dentry *dfs_parent;
static struct dentry *dfs_device_status;
static u32 cpu_use[NR_CPUS]; static u32 cpu_use[NR_CPUS];
...@@ -2707,6 +2712,100 @@ static ssize_t mtip_hw_show_status(struct device *dev, ...@@ -2707,6 +2712,100 @@ static ssize_t mtip_hw_show_status(struct device *dev,
static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
/* debugsfs entries */
static ssize_t show_device_status(struct device_driver *drv, char *buf)
{
int size = 0;
struct driver_data *dd, *tmp;
unsigned long flags;
char id_buf[42];
u16 status = 0;
spin_lock_irqsave(&dev_lock, flags);
size += sprintf(&buf[size], "Devices Present:\n");
list_for_each_entry_safe(dd, tmp, &online_list, online_list) {
if (dd && dd->pdev) {
if (dd->port &&
dd->port->identify &&
dd->port->identify_valid) {
strlcpy(id_buf,
(char *) (dd->port->identify + 10), 21);
status = *(dd->port->identify + 141);
} else {
memset(id_buf, 0, 42);
status = 0;
}
if (dd->port &&
test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) {
size += sprintf(&buf[size],
" device %s %s (ftl rebuild %d %%)\n",
dev_name(&dd->pdev->dev),
id_buf,
status);
} else {
size += sprintf(&buf[size],
" device %s %s\n",
dev_name(&dd->pdev->dev),
id_buf);
}
}
}
size += sprintf(&buf[size], "Devices Being Removed:\n");
list_for_each_entry_safe(dd, tmp, &removing_list, remove_list) {
if (dd && dd->pdev) {
if (dd->port &&
dd->port->identify &&
dd->port->identify_valid) {
strlcpy(id_buf,
(char *) (dd->port->identify+10), 21);
status = *(dd->port->identify + 141);
} else {
memset(id_buf, 0, 42);
status = 0;
}
if (dd->port &&
test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) {
size += sprintf(&buf[size],
" device %s %s (ftl rebuild %d %%)\n",
dev_name(&dd->pdev->dev),
id_buf,
status);
} else {
size += sprintf(&buf[size],
" device %s %s\n",
dev_name(&dd->pdev->dev),
id_buf);
}
}
}
spin_unlock_irqrestore(&dev_lock, flags);
return size;
}
static ssize_t mtip_hw_read_device_status(struct file *f, char __user *ubuf,
size_t len, loff_t *offset)
{
int size = *offset;
char buf[MTIP_DFS_MAX_BUF_SIZE];
if (!len || *offset)
return 0;
size += show_device_status(NULL, buf);
*offset = size <= len ? size : len;
size = copy_to_user(ubuf, buf, *offset);
if (size)
return -EFAULT;
return *offset;
}
static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf,
size_t len, loff_t *offset) size_t len, loff_t *offset)
{ {
...@@ -2801,6 +2900,13 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, ...@@ -2801,6 +2900,13 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf,
return *offset; return *offset;
} }
static const struct file_operations mtip_device_status_fops = {
.owner = THIS_MODULE,
.open = simple_open,
.read = mtip_hw_read_device_status,
.llseek = no_llseek,
};
static const struct file_operations mtip_regs_fops = { static const struct file_operations mtip_regs_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = simple_open, .open = simple_open,
...@@ -4158,6 +4264,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, ...@@ -4158,6 +4264,7 @@ static int mtip_pci_probe(struct pci_dev *pdev,
const struct cpumask *node_mask; const struct cpumask *node_mask;
int cpu, i = 0, j = 0; int cpu, i = 0, j = 0;
int my_node = NUMA_NO_NODE; int my_node = NUMA_NO_NODE;
unsigned long flags;
/* Allocate memory for this devices private data. */ /* Allocate memory for this devices private data. */
my_node = pcibus_to_node(pdev->bus); my_node = pcibus_to_node(pdev->bus);
...@@ -4215,6 +4322,9 @@ static int mtip_pci_probe(struct pci_dev *pdev, ...@@ -4215,6 +4322,9 @@ static int mtip_pci_probe(struct pci_dev *pdev,
dd->pdev = pdev; dd->pdev = pdev;
dd->numa_node = my_node; dd->numa_node = my_node;
INIT_LIST_HEAD(&dd->online_list);
INIT_LIST_HEAD(&dd->remove_list);
memset(dd->workq_name, 0, 32); memset(dd->workq_name, 0, 32);
snprintf(dd->workq_name, 31, "mtipq%d", dd->instance); snprintf(dd->workq_name, 31, "mtipq%d", dd->instance);
...@@ -4304,6 +4414,12 @@ static int mtip_pci_probe(struct pci_dev *pdev, ...@@ -4304,6 +4414,12 @@ static int mtip_pci_probe(struct pci_dev *pdev,
set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
else else
rv = 0; /* device in rebuild state, return 0 from probe */ rv = 0; /* device in rebuild state, return 0 from probe */
/* Add to online list even if in ftl rebuild */
spin_lock_irqsave(&dev_lock, flags);
list_add(&dd->online_list, &online_list);
spin_unlock_irqrestore(&dev_lock, flags);
goto done; goto done;
block_initialize_err: block_initialize_err:
...@@ -4337,9 +4453,15 @@ static void mtip_pci_remove(struct pci_dev *pdev) ...@@ -4337,9 +4453,15 @@ static void mtip_pci_remove(struct pci_dev *pdev)
{ {
struct driver_data *dd = pci_get_drvdata(pdev); struct driver_data *dd = pci_get_drvdata(pdev);
int counter = 0; int counter = 0;
unsigned long flags;
set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
spin_lock_irqsave(&dev_lock, flags);
list_del_init(&dd->online_list);
list_add(&dd->remove_list, &removing_list);
spin_unlock_irqrestore(&dev_lock, flags);
if (mtip_check_surprise_removal(pdev)) { if (mtip_check_surprise_removal(pdev)) {
while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
counter++; counter++;
...@@ -4365,6 +4487,10 @@ static void mtip_pci_remove(struct pci_dev *pdev) ...@@ -4365,6 +4487,10 @@ static void mtip_pci_remove(struct pci_dev *pdev)
pci_disable_msi(pdev); pci_disable_msi(pdev);
spin_lock_irqsave(&dev_lock, flags);
list_del_init(&dd->remove_list);
spin_unlock_irqrestore(&dev_lock, flags);
kfree(dd); kfree(dd);
pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); pcim_iounmap_regions(pdev, 1 << MTIP_ABAR);
} }
...@@ -4512,6 +4638,11 @@ static int __init mtip_init(void) ...@@ -4512,6 +4638,11 @@ static int __init mtip_init(void)
pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
spin_lock_init(&dev_lock);
INIT_LIST_HEAD(&online_list);
INIT_LIST_HEAD(&removing_list);
/* Allocate a major block device number to use with this driver. */ /* Allocate a major block device number to use with this driver. */
error = register_blkdev(0, MTIP_DRV_NAME); error = register_blkdev(0, MTIP_DRV_NAME);
if (error <= 0) { if (error <= 0) {
...@@ -4521,11 +4652,18 @@ static int __init mtip_init(void) ...@@ -4521,11 +4652,18 @@ static int __init mtip_init(void)
} }
mtip_major = error; mtip_major = error;
if (!dfs_parent) { dfs_parent = debugfs_create_dir("rssd", NULL);
dfs_parent = debugfs_create_dir("rssd", NULL); if (IS_ERR_OR_NULL(dfs_parent)) {
if (IS_ERR_OR_NULL(dfs_parent)) { pr_warn("Error creating debugfs parent\n");
pr_warn("Error creating debugfs parent\n"); dfs_parent = NULL;
dfs_parent = NULL; }
if (dfs_parent) {
dfs_device_status = debugfs_create_file("device_status",
S_IRUGO, dfs_parent, NULL,
&mtip_device_status_fops);
if (IS_ERR_OR_NULL(dfs_device_status)) {
pr_err("Error creating device_status node\n");
dfs_device_status = NULL;
} }
} }
......
...@@ -129,9 +129,9 @@ enum { ...@@ -129,9 +129,9 @@ enum {
MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */
MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */
MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */
MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) |
(1 << MTIP_PF_EH_ACTIVE_BIT) | \ (1 << MTIP_PF_EH_ACTIVE_BIT) |
(1 << MTIP_PF_SE_ACTIVE_BIT) | \ (1 << MTIP_PF_SE_ACTIVE_BIT) |
(1 << MTIP_PF_DM_ACTIVE_BIT)), (1 << MTIP_PF_DM_ACTIVE_BIT)),
MTIP_PF_SVC_THD_ACTIVE_BIT = 4, MTIP_PF_SVC_THD_ACTIVE_BIT = 4,
...@@ -144,9 +144,9 @@ enum { ...@@ -144,9 +144,9 @@ enum {
MTIP_DDF_REMOVE_PENDING_BIT = 1, MTIP_DDF_REMOVE_PENDING_BIT = 1,
MTIP_DDF_OVER_TEMP_BIT = 2, MTIP_DDF_OVER_TEMP_BIT = 2,
MTIP_DDF_WRITE_PROTECT_BIT = 3, MTIP_DDF_WRITE_PROTECT_BIT = 3,
MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) |
(1 << MTIP_DDF_SEC_LOCK_BIT) | \ (1 << MTIP_DDF_SEC_LOCK_BIT) |
(1 << MTIP_DDF_OVER_TEMP_BIT) | \ (1 << MTIP_DDF_OVER_TEMP_BIT) |
(1 << MTIP_DDF_WRITE_PROTECT_BIT)), (1 << MTIP_DDF_WRITE_PROTECT_BIT)),
MTIP_DDF_CLEANUP_BIT = 5, MTIP_DDF_CLEANUP_BIT = 5,
...@@ -180,7 +180,7 @@ struct mtip_work { ...@@ -180,7 +180,7 @@ struct mtip_work {
#define MTIP_TRIM_TIMEOUT_MS 240000 #define MTIP_TRIM_TIMEOUT_MS 240000
#define MTIP_MAX_TRIM_ENTRIES 8 #define MTIP_MAX_TRIM_ENTRIES 8
#define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8 #define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8
struct mtip_trim_entry { struct mtip_trim_entry {
u32 lba; /* starting lba of region */ u32 lba; /* starting lba of region */
...@@ -501,6 +501,10 @@ struct driver_data { ...@@ -501,6 +501,10 @@ struct driver_data {
atomic_t irq_workers_active; atomic_t irq_workers_active;
int isr_binding; int isr_binding;
struct list_head online_list; /* linkage for online list */
struct list_head remove_list; /* linkage for removing list */
}; };
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment