aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2010-09-10 12:15:20 -0400
committerRoland Dreier <rolandd@cisco.com>2010-09-28 13:46:33 -0400
commit9e8d1fa3420f489da8a5da47c026511aa71fa50b (patch)
tree333ca70a940fba54cc277db0383b01c3bc6bccf0 /drivers/infiniband
parent05fb9629473690e4be4112f22e1adeb1fe4ad733 (diff)
RDMA/cxgb4: debugfs files for dumping active stags
Add "stags" debugfs file. This is useful for examining the TPTE and PBL entries in adapter memory. It allows scripts to dump just the active entries. Also clean up the "qps" file handlers and shared common code. Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c152
1 files changed, 113 insertions, 39 deletions
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 9bbf491d5d9e..2851bf831fb2 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -49,29 +49,57 @@ static DEFINE_MUTEX(dev_mutex);
49 49
50static struct dentry *c4iw_debugfs_root; 50static struct dentry *c4iw_debugfs_root;
51 51
52struct debugfs_qp_data { 52struct c4iw_debugfs_data {
53 struct c4iw_dev *devp; 53 struct c4iw_dev *devp;
54 char *buf; 54 char *buf;
55 int bufsize; 55 int bufsize;
56 int pos; 56 int pos;
57}; 57};
58 58
59static int count_qps(int id, void *p, void *data) 59static int count_idrs(int id, void *p, void *data)
60{ 60{
61 struct c4iw_qp *qp = p;
62 int *countp = data; 61 int *countp = data;
63 62
64 if (id != qp->wq.sq.qid)
65 return 0;
66
67 *countp = *countp + 1; 63 *countp = *countp + 1;
68 return 0; 64 return 0;
69} 65}
70 66
71static int dump_qps(int id, void *p, void *data) 67static ssize_t debugfs_read(struct file *file, char __user *buf, size_t count,
68 loff_t *ppos)
69{
70 struct c4iw_debugfs_data *d = file->private_data;
71 loff_t pos = *ppos;
72 loff_t avail = d->pos;
73
74 if (pos < 0)
75 return -EINVAL;
76 if (pos >= avail)
77 return 0;
78 if (count > avail - pos)
79 count = avail - pos;
80
81 while (count) {
82 size_t len = 0;
83
84 len = min((int)count, (int)d->pos - (int)pos);
85 if (copy_to_user(buf, d->buf + pos, len))
86 return -EFAULT;
87 if (len == 0)
88 return -EINVAL;
89
90 buf += len;
91 pos += len;
92 count -= len;
93 }
94 count = pos - *ppos;
95 *ppos = pos;
96 return count;
97}
98
99static int dump_qp(int id, void *p, void *data)
72{ 100{
73 struct c4iw_qp *qp = p; 101 struct c4iw_qp *qp = p;
74 struct debugfs_qp_data *qpd = data; 102 struct c4iw_debugfs_data *qpd = data;
75 int space; 103 int space;
76 int cc; 104 int cc;
77 105
@@ -101,7 +129,7 @@ static int dump_qps(int id, void *p, void *data)
101 129
102static int qp_release(struct inode *inode, struct file *file) 130static int qp_release(struct inode *inode, struct file *file)
103{ 131{
104 struct debugfs_qp_data *qpd = file->private_data; 132 struct c4iw_debugfs_data *qpd = file->private_data;
105 if (!qpd) { 133 if (!qpd) {
106 printk(KERN_INFO "%s null qpd?\n", __func__); 134 printk(KERN_INFO "%s null qpd?\n", __func__);
107 return 0; 135 return 0;
@@ -113,7 +141,7 @@ static int qp_release(struct inode *inode, struct file *file)
113 141
114static int qp_open(struct inode *inode, struct file *file) 142static int qp_open(struct inode *inode, struct file *file)
115{ 143{
116 struct debugfs_qp_data *qpd; 144 struct c4iw_debugfs_data *qpd;
117 int ret = 0; 145 int ret = 0;
118 int count = 1; 146 int count = 1;
119 147
@@ -126,7 +154,7 @@ static int qp_open(struct inode *inode, struct file *file)
126 qpd->pos = 0; 154 qpd->pos = 0;
127 155
128 spin_lock_irq(&qpd->devp->lock); 156 spin_lock_irq(&qpd->devp->lock);
129 idr_for_each(&qpd->devp->qpidr, count_qps, &count); 157 idr_for_each(&qpd->devp->qpidr, count_idrs, &count);
130 spin_unlock_irq(&qpd->devp->lock); 158 spin_unlock_irq(&qpd->devp->lock);
131 159
132 qpd->bufsize = count * 128; 160 qpd->bufsize = count * 128;
@@ -137,7 +165,7 @@ static int qp_open(struct inode *inode, struct file *file)
137 } 165 }
138 166
139 spin_lock_irq(&qpd->devp->lock); 167 spin_lock_irq(&qpd->devp->lock);
140 idr_for_each(&qpd->devp->qpidr, dump_qps, qpd); 168 idr_for_each(&qpd->devp->qpidr, dump_qp, qpd);
141 spin_unlock_irq(&qpd->devp->lock); 169 spin_unlock_irq(&qpd->devp->lock);
142 170
143 qpd->buf[qpd->pos++] = 0; 171 qpd->buf[qpd->pos++] = 0;
@@ -149,43 +177,84 @@ out:
149 return ret; 177 return ret;
150} 178}
151 179
152static ssize_t qp_read(struct file *file, char __user *buf, size_t count, 180static const struct file_operations qp_debugfs_fops = {
153 loff_t *ppos) 181 .owner = THIS_MODULE,
182 .open = qp_open,
183 .release = qp_release,
184 .read = debugfs_read,
185};
186
187static int dump_stag(int id, void *p, void *data)
154{ 188{
155 struct debugfs_qp_data *qpd = file->private_data; 189 struct c4iw_debugfs_data *stagd = data;
156 loff_t pos = *ppos; 190 int space;
157 loff_t avail = qpd->pos; 191 int cc;
158 192
159 if (pos < 0) 193 space = stagd->bufsize - stagd->pos - 1;
160 return -EINVAL; 194 if (space == 0)
161 if (pos >= avail) 195 return 1;
196
197 cc = snprintf(stagd->buf + stagd->pos, space, "0x%x\n", id<<8);
198 if (cc < space)
199 stagd->pos += cc;
200 return 0;
201}
202
203static int stag_release(struct inode *inode, struct file *file)
204{
205 struct c4iw_debugfs_data *stagd = file->private_data;
206 if (!stagd) {
207 printk(KERN_INFO "%s null stagd?\n", __func__);
162 return 0; 208 return 0;
163 if (count > avail - pos) 209 }
164 count = avail - pos; 210 kfree(stagd->buf);
211 kfree(stagd);
212 return 0;
213}
165 214
166 while (count) { 215static int stag_open(struct inode *inode, struct file *file)
167 size_t len = 0; 216{
217 struct c4iw_debugfs_data *stagd;
218 int ret = 0;
219 int count = 1;
168 220
169 len = min((int)count, (int)qpd->pos - (int)pos); 221 stagd = kmalloc(sizeof *stagd, GFP_KERNEL);
170 if (copy_to_user(buf, qpd->buf + pos, len)) 222 if (!stagd) {
171 return -EFAULT; 223 ret = -ENOMEM;
172 if (len == 0) 224 goto out;
173 return -EINVAL; 225 }
226 stagd->devp = inode->i_private;
227 stagd->pos = 0;
174 228
175 buf += len; 229 spin_lock_irq(&stagd->devp->lock);
176 pos += len; 230 idr_for_each(&stagd->devp->mmidr, count_idrs, &count);
177 count -= len; 231 spin_unlock_irq(&stagd->devp->lock);
232
233 stagd->bufsize = count * sizeof("0x12345678\n");
234 stagd->buf = kmalloc(stagd->bufsize, GFP_KERNEL);
235 if (!stagd->buf) {
236 ret = -ENOMEM;
237 goto err1;
178 } 238 }
179 count = pos - *ppos; 239
180 *ppos = pos; 240 spin_lock_irq(&stagd->devp->lock);
181 return count; 241 idr_for_each(&stagd->devp->mmidr, dump_stag, stagd);
242 spin_unlock_irq(&stagd->devp->lock);
243
244 stagd->buf[stagd->pos++] = 0;
245 file->private_data = stagd;
246 goto out;
247err1:
248 kfree(stagd);
249out:
250 return ret;
182} 251}
183 252
184static const struct file_operations qp_debugfs_fops = { 253static const struct file_operations stag_debugfs_fops = {
185 .owner = THIS_MODULE, 254 .owner = THIS_MODULE,
186 .open = qp_open, 255 .open = stag_open,
187 .release = qp_release, 256 .release = stag_release,
188 .read = qp_read, 257 .read = debugfs_read,
189}; 258};
190 259
191static int setup_debugfs(struct c4iw_dev *devp) 260static int setup_debugfs(struct c4iw_dev *devp)
@@ -199,6 +268,11 @@ static int setup_debugfs(struct c4iw_dev *devp)
199 (void *)devp, &qp_debugfs_fops); 268 (void *)devp, &qp_debugfs_fops);
200 if (de && de->d_inode) 269 if (de && de->d_inode)
201 de->d_inode->i_size = 4096; 270 de->d_inode->i_size = 4096;
271
272 de = debugfs_create_file("stags", S_IWUSR, devp->debugfs_root,
273 (void *)devp, &stag_debugfs_fops);
274 if (de && de->d_inode)
275 de->d_inode->i_size = 4096;
202 return 0; 276 return 0;
203} 277}
204 278