~ubuntu-branches/ubuntu/wily/spl-linux/wily

« back to all changes in this revision

Viewing changes to module/spl/spl-kstat.c

  • Committer: Package Import Robot
  • Author(s): Liang Guo
  • Date: 2014-07-31 15:16:53 UTC
  • Revision ID: package-import@ubuntu.com-20140731151653-tgao12alohj26jcs
Tags: upstream-0.6.3+git20140731
ImportĀ upstreamĀ versionĀ 0.6.3+git20140731

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
static struct list_head kstat_module_list;
42
42
static kid_t kstat_id;
43
43
 
44
 
static void
 
44
static int
 
45
kstat_resize_raw(kstat_t *ksp)
 
46
{
 
47
        if (ksp->ks_raw_bufsize == KSTAT_RAW_MAX)
 
48
                return ENOMEM;
 
49
 
 
50
        vmem_free(ksp->ks_raw_buf, ksp->ks_raw_bufsize);
 
51
        ksp->ks_raw_bufsize = MIN(ksp->ks_raw_bufsize * 2, KSTAT_RAW_MAX);
 
52
        ksp->ks_raw_buf = vmem_alloc(ksp->ks_raw_bufsize, KM_SLEEP);
 
53
 
 
54
        return 0;
 
55
}
 
56
 
 
57
void
 
58
kstat_waitq_enter(kstat_io_t *kiop)
 
59
{
 
60
        hrtime_t new, delta;
 
61
        ulong_t wcnt;
 
62
 
 
63
        new = gethrtime();
 
64
        delta = new - kiop->wlastupdate;
 
65
        kiop->wlastupdate = new;
 
66
        wcnt = kiop->wcnt++;
 
67
        if (wcnt != 0) {
 
68
                kiop->wlentime += delta * wcnt;
 
69
                kiop->wtime += delta;
 
70
        }
 
71
}
 
72
EXPORT_SYMBOL(kstat_waitq_enter);
 
73
 
 
74
void
 
75
kstat_waitq_exit(kstat_io_t *kiop)
 
76
{
 
77
        hrtime_t new, delta;
 
78
        ulong_t wcnt;
 
79
 
 
80
        new = gethrtime();
 
81
        delta = new - kiop->wlastupdate;
 
82
        kiop->wlastupdate = new;
 
83
        wcnt = kiop->wcnt--;
 
84
        ASSERT((int)wcnt > 0);
 
85
        kiop->wlentime += delta * wcnt;
 
86
        kiop->wtime += delta;
 
87
}
 
88
EXPORT_SYMBOL(kstat_waitq_exit);
 
89
 
 
90
void
 
91
kstat_runq_enter(kstat_io_t *kiop)
 
92
{
 
93
        hrtime_t new, delta;
 
94
        ulong_t rcnt;
 
95
 
 
96
        new = gethrtime();
 
97
        delta = new - kiop->rlastupdate;
 
98
        kiop->rlastupdate = new;
 
99
        rcnt = kiop->rcnt++;
 
100
        if (rcnt != 0) {
 
101
                kiop->rlentime += delta * rcnt;
 
102
                kiop->rtime += delta;
 
103
        }
 
104
}
 
105
EXPORT_SYMBOL(kstat_runq_enter);
 
106
 
 
107
void
 
108
kstat_runq_exit(kstat_io_t *kiop)
 
109
{
 
110
        hrtime_t new, delta;
 
111
        ulong_t rcnt;
 
112
 
 
113
        new = gethrtime();
 
114
        delta = new - kiop->rlastupdate;
 
115
        kiop->rlastupdate = new;
 
116
        rcnt = kiop->rcnt--;
 
117
        ASSERT((int)rcnt > 0);
 
118
        kiop->rlentime += delta * rcnt;
 
119
        kiop->rtime += delta;
 
120
}
 
121
EXPORT_SYMBOL(kstat_runq_exit);
 
122
 
 
123
static int
45
124
kstat_seq_show_headers(struct seq_file *f)
46
125
{
47
126
        kstat_t *ksp = (kstat_t *)f->private;
 
127
        int rc = 0;
 
128
 
48
129
        ASSERT(ksp->ks_magic == KS_MAGIC);
49
130
 
50
131
        seq_printf(f, "%d %d 0x%02x %d %d %lld %lld\n",
54
135
 
55
136
        switch (ksp->ks_type) {
56
137
                case KSTAT_TYPE_RAW:
57
 
                        seq_printf(f, "raw data");
 
138
restart:
 
139
                        if (ksp->ks_raw_ops.headers) {
 
140
                                rc = ksp->ks_raw_ops.headers(
 
141
                                    ksp->ks_raw_buf, ksp->ks_raw_bufsize);
 
142
                                if (rc == ENOMEM && !kstat_resize_raw(ksp))
 
143
                                        goto restart;
 
144
                                if (!rc)
 
145
                                        seq_puts(f, ksp->ks_raw_buf);
 
146
                        } else {
 
147
                                seq_printf(f, "raw data\n");
 
148
                        }
58
149
                        break;
59
150
                case KSTAT_TYPE_NAMED:
60
151
                        seq_printf(f, "%-31s %-4s %s\n",
81
172
                                   "name", "events", "elapsed",
82
173
                                   "min", "max", "start", "stop");
83
174
                        break;
84
 
                case KSTAT_TYPE_TXG:
85
 
                        seq_printf(f,
86
 
                                   "%-8s %-5s %-13s %-12s %-12s %-8s %-8s "
87
 
                                   "%-12s %-12s %-12s\n",
88
 
                                   "txg", "state", "birth",
89
 
                                   "nread", "nwritten", "reads", "writes",
90
 
                                   "otime", "qtime", "stime");
91
 
                        break;
92
175
                default:
93
176
                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
94
177
        }
 
178
 
 
179
        return -rc;
95
180
}
96
181
 
97
182
static int
202
287
}
203
288
 
204
289
static int
205
 
kstat_seq_show_txg(struct seq_file *f, kstat_txg_t *ktp)
206
 
{
207
 
        char state;
208
 
 
209
 
        switch (ktp->state) {
210
 
                case TXG_STATE_OPEN:            state = 'O';    break;
211
 
                case TXG_STATE_QUIESCING:       state = 'Q';    break;
212
 
                case TXG_STATE_SYNCING:         state = 'S';    break;
213
 
                case TXG_STATE_COMMITTED:       state = 'C';    break;
214
 
                default:                        state = '?';    break;
215
 
        }
216
 
 
217
 
        seq_printf(f,
218
 
                   "%-8llu %-5c %-13llu %-12llu %-12llu %-8u %-8u "
219
 
                   "%12lld %12lld %12lld\n", ktp->txg, state, ktp->birth,
220
 
                    ktp->nread, ktp->nwritten, ktp->reads, ktp->writes,
221
 
                    ktp->open_time, ktp->quiesce_time, ktp->sync_time);
222
 
        return 0;
223
 
}
224
 
 
225
 
static int
226
290
kstat_seq_show(struct seq_file *f, void *p)
227
291
{
228
292
        kstat_t *ksp = (kstat_t *)f->private;
232
296
 
233
297
        switch (ksp->ks_type) {
234
298
                case KSTAT_TYPE_RAW:
235
 
                        ASSERT(ksp->ks_ndata == 1);
236
 
                        rc = kstat_seq_show_raw(f, ksp->ks_data,
237
 
                                                ksp->ks_data_size);
 
299
restart:
 
300
                        if (ksp->ks_raw_ops.data) {
 
301
                                rc = ksp->ks_raw_ops.data(
 
302
                                    ksp->ks_raw_buf, ksp->ks_raw_bufsize, p);
 
303
                                if (rc == ENOMEM && !kstat_resize_raw(ksp))
 
304
                                        goto restart;
 
305
                                if (!rc)
 
306
                                        seq_puts(f, ksp->ks_raw_buf);
 
307
                        } else {
 
308
                                ASSERT(ksp->ks_ndata == 1);
 
309
                                rc = kstat_seq_show_raw(f, ksp->ks_data,
 
310
                                                        ksp->ks_data_size);
 
311
                        }
238
312
                        break;
239
313
                case KSTAT_TYPE_NAMED:
240
314
                        rc = kstat_seq_show_named(f, (kstat_named_t *)p);
248
322
                case KSTAT_TYPE_TIMER:
249
323
                        rc = kstat_seq_show_timer(f, (kstat_timer_t *)p);
250
324
                        break;
251
 
                case KSTAT_TYPE_TXG:
252
 
                        rc = kstat_seq_show_txg(f, (kstat_txg_t *)p);
253
 
                        break;
254
325
                default:
255
326
                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
256
327
        }
257
328
 
258
 
        return rc;
 
329
        return -rc;
259
330
}
260
331
 
261
332
int
262
333
kstat_default_update(kstat_t *ksp, int rw)
263
334
{
264
335
        ASSERT(ksp != NULL);
 
336
 
 
337
        if (rw == KSTAT_WRITE)
 
338
                return (EACCES);
 
339
 
265
340
        return 0;
266
341
}
267
342
 
273
348
 
274
349
        switch (ksp->ks_type) {
275
350
                case KSTAT_TYPE_RAW:
276
 
                        rc = ksp->ks_data;
 
351
                        if (ksp->ks_raw_ops.addr)
 
352
                                rc = ksp->ks_raw_ops.addr(ksp, n);
 
353
                        else
 
354
                                rc = ksp->ks_data;
277
355
                        break;
278
356
                case KSTAT_TYPE_NAMED:
279
357
                        rc = ksp->ks_data + n * sizeof(kstat_named_t);
287
365
                case KSTAT_TYPE_TIMER:
288
366
                        rc = ksp->ks_data + n * sizeof(kstat_timer_t);
289
367
                        break;
290
 
                case KSTAT_TYPE_TXG:
291
 
                        rc = ksp->ks_data + n * sizeof(kstat_txg_t);
292
 
                        break;
293
368
                default:
294
369
                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
295
370
        }
305
380
        ASSERT(ksp->ks_magic == KS_MAGIC);
306
381
        SENTRY;
307
382
 
308
 
        mutex_enter(&ksp->ks_lock);
 
383
        mutex_enter(ksp->ks_lock);
 
384
 
 
385
        if (ksp->ks_type == KSTAT_TYPE_RAW) {
 
386
                ksp->ks_raw_bufsize = PAGE_SIZE;
 
387
                ksp->ks_raw_buf = vmem_alloc(ksp->ks_raw_bufsize, KM_SLEEP);
 
388
        }
309
389
 
310
390
        /* Dynamically update kstat, on error existing kstats are used */
311
391
        (void) ksp->ks_update(ksp, KSTAT_READ);
312
392
 
313
393
        ksp->ks_snaptime = gethrtime();
314
394
 
315
 
        if (!n)
316
 
                kstat_seq_show_headers(f);
 
395
        if (!n && kstat_seq_show_headers(f))
 
396
                SRETURN(NULL);
317
397
 
318
398
        if (n >= ksp->ks_ndata)
319
399
                SRETURN(NULL);
338
418
static void
339
419
kstat_seq_stop(struct seq_file *f, void *v)
340
420
{
341
 
        kstat_t *ksp = (kstat_t *)f->private;
342
 
        ASSERT(ksp->ks_magic == KS_MAGIC);
343
 
 
344
 
        mutex_exit(&ksp->ks_lock);
 
421
        kstat_t *ksp = (kstat_t *)f->private;
 
422
        ASSERT(ksp->ks_magic == KS_MAGIC);
 
423
 
 
424
        if (ksp->ks_type == KSTAT_TYPE_RAW)
 
425
                vmem_free(ksp->ks_raw_buf, ksp->ks_raw_bufsize);
 
426
 
 
427
        mutex_exit(ksp->ks_lock);
345
428
}
346
429
 
347
430
static struct seq_operations kstat_seq_ops = {
408
491
        return rc;
409
492
}
410
493
 
 
494
static ssize_t
 
495
proc_kstat_write(struct file *filp, const char __user *buf,
 
496
                 size_t len, loff_t *ppos)
 
497
{
 
498
        struct seq_file *f = filp->private_data;
 
499
        kstat_t *ksp = f->private;
 
500
        int rc;
 
501
 
 
502
        ASSERT(ksp->ks_magic == KS_MAGIC);
 
503
 
 
504
        mutex_enter(ksp->ks_lock);
 
505
        rc = ksp->ks_update(ksp, KSTAT_WRITE);
 
506
        mutex_exit(ksp->ks_lock);
 
507
 
 
508
        if (rc)
 
509
                return (-rc);
 
510
 
 
511
        *ppos += len;
 
512
        return (len);
 
513
}
 
514
 
411
515
static struct file_operations proc_kstat_operations = {
412
 
        .open           = proc_kstat_open,
413
 
        .read           = seq_read,
414
 
        .llseek         = seq_lseek,
415
 
        .release        = seq_release,
 
516
        .open           = proc_kstat_open,
 
517
        .write          = proc_kstat_write,
 
518
        .read           = seq_read,
 
519
        .llseek         = seq_lseek,
 
520
        .release        = seq_release,
416
521
};
417
522
 
 
523
void
 
524
__kstat_set_raw_ops(kstat_t *ksp,
 
525
                    int (*headers)(char *buf, size_t size),
 
526
                    int (*data)(char *buf, size_t size, void *data),
 
527
                    void *(*addr)(kstat_t *ksp, loff_t index))
 
528
{
 
529
        ksp->ks_raw_ops.headers = headers;
 
530
        ksp->ks_raw_ops.data    = data;
 
531
        ksp->ks_raw_ops.addr    = addr;
 
532
}
 
533
EXPORT_SYMBOL(__kstat_set_raw_ops);
 
534
 
418
535
kstat_t *
419
536
__kstat_create(const char *ks_module, int ks_instance, const char *ks_name,
420
537
             const char *ks_class, uchar_t ks_type, uint_t ks_ndata,
440
557
        mutex_exit(&kstat_module_lock);
441
558
 
442
559
        ksp->ks_magic = KS_MAGIC;
443
 
        mutex_init(&ksp->ks_lock, NULL, MUTEX_DEFAULT, NULL);
 
560
        mutex_init(&ksp->ks_private_lock, NULL, MUTEX_DEFAULT, NULL);
 
561
        ksp->ks_lock = &ksp->ks_private_lock;
444
562
        INIT_LIST_HEAD(&ksp->ks_list);
445
563
 
446
564
        ksp->ks_crtime = gethrtime();
453
571
        ksp->ks_flags = ks_flags;
454
572
        ksp->ks_update = kstat_default_update;
455
573
        ksp->ks_private = NULL;
 
574
        ksp->ks_raw_ops.headers = NULL;
 
575
        ksp->ks_raw_ops.data = NULL;
 
576
        ksp->ks_raw_ops.addr = NULL;
 
577
        ksp->ks_raw_buf = NULL;
 
578
        ksp->ks_raw_bufsize = 0;
456
579
 
457
580
        switch (ksp->ks_type) {
458
581
                case KSTAT_TYPE_RAW:
475
598
                        ksp->ks_ndata = ks_ndata;
476
599
                        ksp->ks_data_size = ks_ndata * sizeof(kstat_timer_t);
477
600
                        break;
478
 
                case KSTAT_TYPE_TXG:
479
 
                        ksp->ks_ndata = ks_ndata;
480
 
                        ksp->ks_data_size = ks_ndata * sizeof(kstat_timer_t);
481
 
                        break;
482
601
                default:
483
602
                        PANIC("Undefined kstat type %d\n", ksp->ks_type);
484
603
        }
486
605
        if (ksp->ks_flags & KSTAT_FLAG_VIRTUAL) {
487
606
                ksp->ks_data = NULL;
488
607
        } else {
489
 
                ksp->ks_data = kmem_alloc(ksp->ks_data_size, KM_SLEEP);
 
608
                ksp->ks_data = kmem_zalloc(ksp->ks_data_size, KM_SLEEP);
490
609
                if (ksp->ks_data == NULL) {
491
610
                        kmem_free(ksp, sizeof(*ksp));
492
611
                        ksp = NULL;
524
643
 
525
644
        list_add_tail(&ksp->ks_list, &module->ksm_kstat_list);
526
645
 
527
 
        mutex_enter(&ksp->ks_lock);
 
646
        mutex_enter(ksp->ks_lock);
528
647
        ksp->ks_owner = module;
529
 
        ksp->ks_proc = proc_create_data(ksp->ks_name, 0444,
 
648
        ksp->ks_proc = proc_create_data(ksp->ks_name, 0644,
530
649
            module->ksm_proc, &proc_kstat_operations, (void *)ksp);
531
650
        if (ksp->ks_proc == NULL) {
532
651
                list_del_init(&ksp->ks_list);
533
652
                if (list_empty(&module->ksm_kstat_list))
534
653
                        kstat_delete_module(module);
535
654
        }
536
 
        mutex_exit(&ksp->ks_lock);
 
655
        mutex_exit(ksp->ks_lock);
537
656
out:
538
657
        mutex_exit(&kstat_module_lock);
539
658
}
559
678
        if (!(ksp->ks_flags & KSTAT_FLAG_VIRTUAL))
560
679
                kmem_free(ksp->ks_data, ksp->ks_data_size);
561
680
 
562
 
        mutex_destroy(&ksp->ks_lock);
 
681
        ksp->ks_lock = NULL;
 
682
        mutex_destroy(&ksp->ks_private_lock);
563
683
        kmem_free(ksp, sizeof(*ksp));
564
684
 
565
685
        return;