aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVipul Pandya <vipul@chelsio.com>2012-05-18 05:59:27 -0400
committerRoland Dreier <roland@purestorage.com>2012-05-18 16:22:29 -0400
commit8d81ef34b249109084b2f3c4bb826d0417ef5814 (patch)
tree77dbd13539db2053cada804c35e4cccd26f4e4c0
parent3069ee9bc451d90a2fa8c3c7ef2774744d9d3bb0 (diff)
RDMA/cxgb4: Add debugfs RDMA memory stats
Signed-off-by: Vipul Pandya <vipul@chelsio.com> Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c78
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h17
-rw-r--r--drivers/infiniband/hw/cxgb4/mem.c11
-rw-r--r--drivers/infiniband/hw/cxgb4/provider.c8
-rw-r--r--drivers/infiniband/hw/cxgb4/resource.c44
5 files changed, 155 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 6d0df6ec161b..84831119c596 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -240,6 +240,62 @@ static const struct file_operations stag_debugfs_fops = {
240 .llseek = default_llseek, 240 .llseek = default_llseek,
241}; 241};
242 242
243static int stats_show(struct seq_file *seq, void *v)
244{
245 struct c4iw_dev *dev = seq->private;
246
247 seq_printf(seq, " Object: %10s %10s %10s\n", "Total", "Current", "Max");
248 seq_printf(seq, " PDID: %10llu %10llu %10llu\n",
249 dev->rdev.stats.pd.total, dev->rdev.stats.pd.cur,
250 dev->rdev.stats.pd.max);
251 seq_printf(seq, " QID: %10llu %10llu %10llu\n",
252 dev->rdev.stats.qid.total, dev->rdev.stats.qid.cur,
253 dev->rdev.stats.qid.max);
254 seq_printf(seq, " TPTMEM: %10llu %10llu %10llu\n",
255 dev->rdev.stats.stag.total, dev->rdev.stats.stag.cur,
256 dev->rdev.stats.stag.max);
257 seq_printf(seq, " PBLMEM: %10llu %10llu %10llu\n",
258 dev->rdev.stats.pbl.total, dev->rdev.stats.pbl.cur,
259 dev->rdev.stats.pbl.max);
260 seq_printf(seq, " RQTMEM: %10llu %10llu %10llu\n",
261 dev->rdev.stats.rqt.total, dev->rdev.stats.rqt.cur,
262 dev->rdev.stats.rqt.max);
263 seq_printf(seq, " OCQPMEM: %10llu %10llu %10llu\n",
264 dev->rdev.stats.ocqp.total, dev->rdev.stats.ocqp.cur,
265 dev->rdev.stats.ocqp.max);
266 return 0;
267}
268
269static int stats_open(struct inode *inode, struct file *file)
270{
271 return single_open(file, stats_show, inode->i_private);
272}
273
274static ssize_t stats_clear(struct file *file, const char __user *buf,
275 size_t count, loff_t *pos)
276{
277 struct c4iw_dev *dev = ((struct seq_file *)file->private_data)->private;
278
279 mutex_lock(&dev->rdev.stats.lock);
280 dev->rdev.stats.pd.max = 0;
281 dev->rdev.stats.qid.max = 0;
282 dev->rdev.stats.stag.max = 0;
283 dev->rdev.stats.pbl.max = 0;
284 dev->rdev.stats.rqt.max = 0;
285 dev->rdev.stats.ocqp.max = 0;
286 mutex_unlock(&dev->rdev.stats.lock);
287 return count;
288}
289
290static const struct file_operations stats_debugfs_fops = {
291 .owner = THIS_MODULE,
292 .open = stats_open,
293 .release = single_release,
294 .read = seq_read,
295 .llseek = seq_lseek,
296 .write = stats_clear,
297};
298
243static int setup_debugfs(struct c4iw_dev *devp) 299static int setup_debugfs(struct c4iw_dev *devp)
244{ 300{
245 struct dentry *de; 301 struct dentry *de;
@@ -256,6 +312,12 @@ static int setup_debugfs(struct c4iw_dev *devp)
256 (void *)devp, &stag_debugfs_fops); 312 (void *)devp, &stag_debugfs_fops);
257 if (de && de->d_inode) 313 if (de && de->d_inode)
258 de->d_inode->i_size = 4096; 314 de->d_inode->i_size = 4096;
315
316 de = debugfs_create_file("stats", S_IWUSR, devp->debugfs_root,
317 (void *)devp, &stats_debugfs_fops);
318 if (de && de->d_inode)
319 de->d_inode->i_size = 4096;
320
259 return 0; 321 return 0;
260} 322}
261 323
@@ -269,9 +331,13 @@ void c4iw_release_dev_ucontext(struct c4iw_rdev *rdev,
269 list_for_each_safe(pos, nxt, &uctx->qpids) { 331 list_for_each_safe(pos, nxt, &uctx->qpids) {
270 entry = list_entry(pos, struct c4iw_qid_list, entry); 332 entry = list_entry(pos, struct c4iw_qid_list, entry);
271 list_del_init(&entry->entry); 333 list_del_init(&entry->entry);
272 if (!(entry->qid & rdev->qpmask)) 334 if (!(entry->qid & rdev->qpmask)) {
273 c4iw_put_resource(&rdev->resource.qid_fifo, entry->qid, 335 c4iw_put_resource(&rdev->resource.qid_fifo, entry->qid,
274 &rdev->resource.qid_fifo_lock); 336 &rdev->resource.qid_fifo_lock);
337 mutex_lock(&rdev->stats.lock);
338 rdev->stats.qid.cur -= rdev->qpmask + 1;
339 mutex_unlock(&rdev->stats.lock);
340 }
275 kfree(entry); 341 kfree(entry);
276 } 342 }
277 343
@@ -332,6 +398,13 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
332 goto err1; 398 goto err1;
333 } 399 }
334 400
401 rdev->stats.pd.total = T4_MAX_NUM_PD;
402 rdev->stats.stag.total = rdev->lldi.vr->stag.size;
403 rdev->stats.pbl.total = rdev->lldi.vr->pbl.size;
404 rdev->stats.rqt.total = rdev->lldi.vr->rq.size;
405 rdev->stats.ocqp.total = rdev->lldi.vr->ocq.size;
406 rdev->stats.qid.total = rdev->lldi.vr->qp.size;
407
335 err = c4iw_init_resource(rdev, c4iw_num_stags(rdev), T4_MAX_NUM_PD); 408 err = c4iw_init_resource(rdev, c4iw_num_stags(rdev), T4_MAX_NUM_PD);
336 if (err) { 409 if (err) {
337 printk(KERN_ERR MOD "error %d initializing resources\n", err); 410 printk(KERN_ERR MOD "error %d initializing resources\n", err);
@@ -440,6 +513,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
440 idr_init(&devp->qpidr); 513 idr_init(&devp->qpidr);
441 idr_init(&devp->mmidr); 514 idr_init(&devp->mmidr);
442 spin_lock_init(&devp->lock); 515 spin_lock_init(&devp->lock);
516 mutex_init(&devp->rdev.stats.lock);
443 517
444 if (c4iw_debugfs_root) { 518 if (c4iw_debugfs_root) {
445 devp->debugfs_root = debugfs_create_dir( 519 devp->debugfs_root = debugfs_create_dir(
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 1357c5bf209b..a8490746d86c 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -103,6 +103,22 @@ enum c4iw_rdev_flags {
103 T4_FATAL_ERROR = (1<<0), 103 T4_FATAL_ERROR = (1<<0),
104}; 104};
105 105
106struct c4iw_stat {
107 u64 total;
108 u64 cur;
109 u64 max;
110};
111
112struct c4iw_stats {
113 struct mutex lock;
114 struct c4iw_stat qid;
115 struct c4iw_stat pd;
116 struct c4iw_stat stag;
117 struct c4iw_stat pbl;
118 struct c4iw_stat rqt;
119 struct c4iw_stat ocqp;
120};
121
106struct c4iw_rdev { 122struct c4iw_rdev {
107 struct c4iw_resource resource; 123 struct c4iw_resource resource;
108 unsigned long qpshift; 124 unsigned long qpshift;
@@ -117,6 +133,7 @@ struct c4iw_rdev {
117 struct cxgb4_lld_info lldi; 133 struct cxgb4_lld_info lldi;
118 unsigned long oc_mw_pa; 134 unsigned long oc_mw_pa;
119 void __iomem *oc_mw_kva; 135 void __iomem *oc_mw_kva;
136 struct c4iw_stats stats;
120}; 137};
121 138
122static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) 139static inline int c4iw_fatal_error(struct c4iw_rdev *rdev)
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index 40c835309e49..2a87379f52a3 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -135,6 +135,11 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
135 &rdev->resource.tpt_fifo_lock); 135 &rdev->resource.tpt_fifo_lock);
136 if (!stag_idx) 136 if (!stag_idx)
137 return -ENOMEM; 137 return -ENOMEM;
138 mutex_lock(&rdev->stats.lock);
139 rdev->stats.stag.cur += 32;
140 if (rdev->stats.stag.cur > rdev->stats.stag.max)
141 rdev->stats.stag.max = rdev->stats.stag.cur;
142 mutex_unlock(&rdev->stats.lock);
138 *stag = (stag_idx << 8) | (atomic_inc_return(&key) & 0xff); 143 *stag = (stag_idx << 8) | (atomic_inc_return(&key) & 0xff);
139 } 144 }
140 PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n", 145 PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n",
@@ -165,9 +170,13 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
165 (rdev->lldi.vr->stag.start >> 5), 170 (rdev->lldi.vr->stag.start >> 5),
166 sizeof(tpt), &tpt); 171 sizeof(tpt), &tpt);
167 172
168 if (reset_tpt_entry) 173 if (reset_tpt_entry) {
169 c4iw_put_resource(&rdev->resource.tpt_fifo, stag_idx, 174 c4iw_put_resource(&rdev->resource.tpt_fifo, stag_idx,
170 &rdev->resource.tpt_fifo_lock); 175 &rdev->resource.tpt_fifo_lock);
176 mutex_lock(&rdev->stats.lock);
177 rdev->stats.stag.cur -= 32;
178 mutex_unlock(&rdev->stats.lock);
179 }
171 return err; 180 return err;
172} 181}
173 182
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index be1c18f44400..8d58736f9b4f 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -190,6 +190,9 @@ static int c4iw_deallocate_pd(struct ib_pd *pd)
190 PDBG("%s ibpd %p pdid 0x%x\n", __func__, pd, php->pdid); 190 PDBG("%s ibpd %p pdid 0x%x\n", __func__, pd, php->pdid);
191 c4iw_put_resource(&rhp->rdev.resource.pdid_fifo, php->pdid, 191 c4iw_put_resource(&rhp->rdev.resource.pdid_fifo, php->pdid,
192 &rhp->rdev.resource.pdid_fifo_lock); 192 &rhp->rdev.resource.pdid_fifo_lock);
193 mutex_lock(&rhp->rdev.stats.lock);
194 rhp->rdev.stats.pd.cur--;
195 mutex_unlock(&rhp->rdev.stats.lock);
193 kfree(php); 196 kfree(php);
194 return 0; 197 return 0;
195} 198}
@@ -222,6 +225,11 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
222 return ERR_PTR(-EFAULT); 225 return ERR_PTR(-EFAULT);
223 } 226 }
224 } 227 }
228 mutex_lock(&rhp->rdev.stats.lock);
229 rhp->rdev.stats.pd.cur++;
230 if (rhp->rdev.stats.pd.cur > rhp->rdev.stats.pd.max)
231 rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur;
232 mutex_unlock(&rhp->rdev.stats.lock);
225 PDBG("%s pdid 0x%0x ptr 0x%p\n", __func__, pdid, php); 233 PDBG("%s pdid 0x%0x ptr 0x%p\n", __func__, pdid, php);
226 return &php->ibpd; 234 return &php->ibpd;
227} 235}
diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c
index 407ff3924150..1b948d192d32 100644
--- a/drivers/infiniband/hw/cxgb4/resource.c
+++ b/drivers/infiniband/hw/cxgb4/resource.c
@@ -185,6 +185,9 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
185 &rdev->resource.qid_fifo_lock); 185 &rdev->resource.qid_fifo_lock);
186 if (!qid) 186 if (!qid)
187 goto out; 187 goto out;
188 mutex_lock(&rdev->stats.lock);
189 rdev->stats.qid.cur += rdev->qpmask + 1;
190 mutex_unlock(&rdev->stats.lock);
188 for (i = qid+1; i & rdev->qpmask; i++) { 191 for (i = qid+1; i & rdev->qpmask; i++) {
189 entry = kmalloc(sizeof *entry, GFP_KERNEL); 192 entry = kmalloc(sizeof *entry, GFP_KERNEL);
190 if (!entry) 193 if (!entry)
@@ -213,6 +216,10 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
213out: 216out:
214 mutex_unlock(&uctx->lock); 217 mutex_unlock(&uctx->lock);
215 PDBG("%s qid 0x%x\n", __func__, qid); 218 PDBG("%s qid 0x%x\n", __func__, qid);
219 mutex_lock(&rdev->stats.lock);
220 if (rdev->stats.qid.cur > rdev->stats.qid.max)
221 rdev->stats.qid.max = rdev->stats.qid.cur;
222 mutex_unlock(&rdev->stats.lock);
216 return qid; 223 return qid;
217} 224}
218 225
@@ -249,6 +256,9 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
249 &rdev->resource.qid_fifo_lock); 256 &rdev->resource.qid_fifo_lock);
250 if (!qid) 257 if (!qid)
251 goto out; 258 goto out;
259 mutex_lock(&rdev->stats.lock);
260 rdev->stats.qid.cur += rdev->qpmask + 1;
261 mutex_unlock(&rdev->stats.lock);
252 for (i = qid+1; i & rdev->qpmask; i++) { 262 for (i = qid+1; i & rdev->qpmask; i++) {
253 entry = kmalloc(sizeof *entry, GFP_KERNEL); 263 entry = kmalloc(sizeof *entry, GFP_KERNEL);
254 if (!entry) 264 if (!entry)
@@ -277,6 +287,10 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
277out: 287out:
278 mutex_unlock(&uctx->lock); 288 mutex_unlock(&uctx->lock);
279 PDBG("%s qid 0x%x\n", __func__, qid); 289 PDBG("%s qid 0x%x\n", __func__, qid);
290 mutex_lock(&rdev->stats.lock);
291 if (rdev->stats.qid.cur > rdev->stats.qid.max)
292 rdev->stats.qid.max = rdev->stats.qid.cur;
293 mutex_unlock(&rdev->stats.lock);
280 return qid; 294 return qid;
281} 295}
282 296
@@ -315,12 +329,22 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size)
315 if (!addr) 329 if (!addr)
316 printk_ratelimited(KERN_WARNING MOD "%s: Out of PBL memory\n", 330 printk_ratelimited(KERN_WARNING MOD "%s: Out of PBL memory\n",
317 pci_name(rdev->lldi.pdev)); 331 pci_name(rdev->lldi.pdev));
332 if (addr) {
333 mutex_lock(&rdev->stats.lock);
334 rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT);
335 if (rdev->stats.pbl.cur > rdev->stats.pbl.max)
336 rdev->stats.pbl.max = rdev->stats.pbl.cur;
337 mutex_unlock(&rdev->stats.lock);
338 }
318 return (u32)addr; 339 return (u32)addr;
319} 340}
320 341
321void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) 342void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size)
322{ 343{
323 PDBG("%s addr 0x%x size %d\n", __func__, addr, size); 344 PDBG("%s addr 0x%x size %d\n", __func__, addr, size);
345 mutex_lock(&rdev->stats.lock);
346 rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT);
347 mutex_unlock(&rdev->stats.lock);
324 gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); 348 gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size);
325} 349}
326 350
@@ -377,12 +401,22 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size)
377 if (!addr) 401 if (!addr)
378 printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n", 402 printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n",
379 pci_name(rdev->lldi.pdev)); 403 pci_name(rdev->lldi.pdev));
404 if (addr) {
405 mutex_lock(&rdev->stats.lock);
406 rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT);
407 if (rdev->stats.rqt.cur > rdev->stats.rqt.max)
408 rdev->stats.rqt.max = rdev->stats.rqt.cur;
409 mutex_unlock(&rdev->stats.lock);
410 }
380 return (u32)addr; 411 return (u32)addr;
381} 412}
382 413
383void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) 414void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size)
384{ 415{
385 PDBG("%s addr 0x%x size %d\n", __func__, addr, size << 6); 416 PDBG("%s addr 0x%x size %d\n", __func__, addr, size << 6);
417 mutex_lock(&rdev->stats.lock);
418 rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT);
419 mutex_unlock(&rdev->stats.lock);
386 gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); 420 gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6);
387} 421}
388 422
@@ -433,12 +467,22 @@ u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size)
433{ 467{
434 unsigned long addr = gen_pool_alloc(rdev->ocqp_pool, size); 468 unsigned long addr = gen_pool_alloc(rdev->ocqp_pool, size);
435 PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size); 469 PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size);
470 if (addr) {
471 mutex_lock(&rdev->stats.lock);
472 rdev->stats.ocqp.cur += roundup(size, 1 << MIN_OCQP_SHIFT);
473 if (rdev->stats.ocqp.cur > rdev->stats.ocqp.max)
474 rdev->stats.ocqp.max = rdev->stats.ocqp.cur;
475 mutex_unlock(&rdev->stats.lock);
476 }
436 return (u32)addr; 477 return (u32)addr;
437} 478}
438 479
439void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size) 480void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size)
440{ 481{
441 PDBG("%s addr 0x%x size %d\n", __func__, addr, size); 482 PDBG("%s addr 0x%x size %d\n", __func__, addr, size);
483 mutex_lock(&rdev->stats.lock);
484 rdev->stats.ocqp.cur -= roundup(size, 1 << MIN_OCQP_SHIFT);
485 mutex_unlock(&rdev->stats.lock);
442 gen_pool_free(rdev->ocqp_pool, (unsigned long)addr, size); 486 gen_pool_free(rdev->ocqp_pool, (unsigned long)addr, size);
443} 487}
444 488