Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Commit

Permalink
Kstat to use private lock by default
Browse files Browse the repository at this point in the history
While porting Illumos #3537 I found that ks_lock member of kstat_t
structure is different between Illumos and SPL. It is a pointer to
the kmutex_t in Illumos, but the mutex lock itself in SPL.
Apparently Illumos kstat API allows consumer to override the lock
if required. With SPL implementation it is not possible anymore.

Things were alright until the first attempt to actually override
the lock. Porting of Illumos #3537 introduced such code for the
first time.

In order to provide the Solaris/Illumos like functionality we:
  1. convert ks_lock to "kmutex_t *ks_lock"
  2. create a new field "kmutex_t ks_private_lock"
  3. On kstat_create() ks_lock = &ks_private_lock

Thus if consumer doesn't care we still have our internal lock in use.
If, however, consumer does care she has a chance to set ks_lock to
anything else before calling kstat_install().

The rest of the code will use ks_lock regardless of its origin.

Signed-off-by: Ned Bass <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Issue #286
  • Loading branch information
Cyril Plisko authored and behlendorf committed Oct 25, 2013
1 parent ce07767 commit ffbf0e5
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 9 deletions.
3 changes: 2 additions & 1 deletion include/sys/kstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ struct kstat_s {
struct proc_dir_entry *ks_proc; /* proc linkage */
kstat_update_t *ks_update; /* dynamic updates */
void *ks_private; /* private data */
kmutex_t ks_lock; /* kstat data lock */
kmutex_t ks_private_lock; /* kstat private data lock */
kmutex_t *ks_lock; /* kstat data lock */
struct list_head ks_list; /* kstat linkage */
kstat_module_t *ks_owner; /* kstat module linkage */
kstat_raw_ops_t ks_raw_ops; /* ops table for raw type */
Expand Down
18 changes: 10 additions & 8 deletions module/spl/spl-kstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ kstat_seq_start(struct seq_file *f, loff_t *pos)
ASSERT(ksp->ks_magic == KS_MAGIC);
SENTRY;

mutex_enter(&ksp->ks_lock);
mutex_enter(ksp->ks_lock);

if (ksp->ks_type == KSTAT_TYPE_RAW) {
ksp->ks_raw_bufsize = PAGE_SIZE;
Expand Down Expand Up @@ -352,13 +352,13 @@ kstat_seq_next(struct seq_file *f, void *p, loff_t *pos)
static void
kstat_seq_stop(struct seq_file *f, void *v)
{
kstat_t *ksp = (kstat_t *)f->private;
ASSERT(ksp->ks_magic == KS_MAGIC);
kstat_t *ksp = (kstat_t *)f->private;
ASSERT(ksp->ks_magic == KS_MAGIC);

if (ksp->ks_type == KSTAT_TYPE_RAW)
vmem_free(ksp->ks_raw_buf, ksp->ks_raw_bufsize);

mutex_exit(&ksp->ks_lock);
mutex_exit(ksp->ks_lock);
}

static struct seq_operations kstat_seq_ops = {
Expand Down Expand Up @@ -491,7 +491,8 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name,
mutex_exit(&kstat_module_lock);

ksp->ks_magic = KS_MAGIC;
mutex_init(&ksp->ks_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&ksp->ks_private_lock, NULL, MUTEX_DEFAULT, NULL);
ksp->ks_lock = &ksp->ks_private_lock;
INIT_LIST_HEAD(&ksp->ks_list);

ksp->ks_crtime = gethrtime();
Expand Down Expand Up @@ -576,7 +577,7 @@ __kstat_install(kstat_t *ksp)

list_add_tail(&ksp->ks_list, &module->ksm_kstat_list);

mutex_enter(&ksp->ks_lock);
mutex_enter(ksp->ks_lock);
ksp->ks_owner = module;
ksp->ks_proc = proc_create_data(ksp->ks_name, 0644,
module->ksm_proc, &proc_kstat_operations, (void *)ksp);
Expand All @@ -585,7 +586,7 @@ __kstat_install(kstat_t *ksp)
if (list_empty(&module->ksm_kstat_list))
kstat_delete_module(module);
}
mutex_exit(&ksp->ks_lock);
mutex_exit(ksp->ks_lock);
out:
mutex_exit(&kstat_module_lock);
}
Expand All @@ -611,7 +612,8 @@ __kstat_delete(kstat_t *ksp)
if (!(ksp->ks_flags & KSTAT_FLAG_VIRTUAL))
kmem_free(ksp->ks_data, ksp->ks_data_size);

mutex_destroy(&ksp->ks_lock);
ksp->ks_lock = NULL;
mutex_destroy(&ksp->ks_private_lock);
kmem_free(ksp, sizeof(*ksp));

return;
Expand Down

0 comments on commit ffbf0e5

Please sign in to comment.