diff options
author | Steve Wise <swise@opengridcomputing.com> | 2010-09-10 12:15:20 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-09-28 13:46:33 -0400 |
commit | 9e8d1fa3420f489da8a5da47c026511aa71fa50b (patch) | |
tree | 333ca70a940fba54cc277db0383b01c3bc6bccf0 | |
parent | 05fb9629473690e4be4112f22e1adeb1fe4ad733 (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>
-rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 152 |
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 | ||
50 | static struct dentry *c4iw_debugfs_root; | 50 | static struct dentry *c4iw_debugfs_root; |
51 | 51 | ||
52 | struct debugfs_qp_data { | 52 | struct 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 | ||
59 | static int count_qps(int id, void *p, void *data) | 59 | static 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 | ||
71 | static int dump_qps(int id, void *p, void *data) | 67 | static 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 | |||
99 | static 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 | ||
102 | static int qp_release(struct inode *inode, struct file *file) | 130 | static 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 | ||
114 | static int qp_open(struct inode *inode, struct file *file) | 142 | static 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 | ||
152 | static ssize_t qp_read(struct file *file, char __user *buf, size_t count, | 180 | static 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 | |||
187 | static 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 | |||
203 | static 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) { | 215 | static 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; | ||
247 | err1: | ||
248 | kfree(stagd); | ||
249 | out: | ||
250 | return ret; | ||
182 | } | 251 | } |
183 | 252 | ||
184 | static const struct file_operations qp_debugfs_fops = { | 253 | static 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 | ||
191 | static int setup_debugfs(struct c4iw_dev *devp) | 260 | static 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 | ||