2002-12-18 22:08:39

by Stephen Hemminger

[permalink] [raw]
Subject: [PATCH] (5/5) improved notifier callback mechanism -- remove old locking

After the previous patches, the notifier interface now has it's own
locking. Therefore the existing locking done by the profile interface
is superfluous.

This has been tested by repeated loading/unloading the oprofile driver
while profiling was on.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or
higher.
# This patch includes the following deltas:
# ChangeSet 1.985 -> 1.986
# arch/i386/kernel/profile.c 1.2 -> 1.3
# kernel/profile.c 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/12/17 [email protected] 1.986
# Locking now handled by notifier
# --------------------------------------------
#
diff -Nru a/arch/i386/kernel/profile.c b/arch/i386/kernel/profile.c
--- a/arch/i386/kernel/profile.c Tue Dec 17 11:25:47 2002
+++ b/arch/i386/kernel/profile.c Tue Dec 17 11:25:47 2002
@@ -6,40 +6,25 @@
*/

#include <linux/profile.h>
-#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <linux/irq.h>
#include <asm/hw_irq.h>

static LIST_HEAD(profile_listeners);
-static rwlock_t profile_lock = RW_LOCK_UNLOCKED;

int register_profile_notifier(struct notifier_block * nb)
{
- int err;
- write_lock_irq(&profile_lock);
- err = notifier_chain_register(&profile_listeners, nb);
- write_unlock_irq(&profile_lock);
- return err;
+ return notifier_chain_register(&profile_listeners, nb);
}


int unregister_profile_notifier(struct notifier_block * nb)
{
- int err;
- write_lock_irq(&profile_lock);
- err = notifier_chain_unregister(&profile_listeners, nb);
- write_unlock_irq(&profile_lock);
- return err;
+ return notifier_chain_unregister(&profile_listeners, nb);
}


void x86_profile_hook(struct pt_regs * regs)
{
- /* we would not even need this lock if
- * we had a global cli() on register/unregister
- */
- read_lock(&profile_lock);
notifier_call_chain(&profile_listeners, 0, regs);
- read_unlock(&profile_lock);
}
diff -Nru a/kernel/profile.c b/kernel/profile.c
--- a/kernel/profile.c Tue Dec 17 11:25:47 2002
+++ b/kernel/profile.c Tue Dec 17 11:25:47 2002
@@ -47,38 +47,29 @@

#ifdef CONFIG_PROFILING

-static DECLARE_RWSEM(profile_rwsem);
static LIST_HEAD(exit_task_notifier);
static LIST_HEAD(exit_mmap_notifier);
static LIST_HEAD(exec_unmap_notifier);

void profile_exit_task(struct task_struct * task)
{
- down_read(&profile_rwsem);
notifier_call_chain(&exit_task_notifier, 0, task);
- up_read(&profile_rwsem);
}

void profile_exit_mmap(struct mm_struct * mm)
{
- down_read(&profile_rwsem);
notifier_call_chain(&exit_mmap_notifier, 0, mm);
- up_read(&profile_rwsem);
}

void profile_exec_unmap(struct mm_struct * mm)
{
- down_read(&profile_rwsem);
notifier_call_chain(&exec_unmap_notifier, 0, mm);
- up_read(&profile_rwsem);
}

int profile_event_register(enum profile_type type, struct
notifier_block * n)
{
int err = -EINVAL;

- down_write(&profile_rwsem);
-
switch (type) {
case EXIT_TASK:
err = notifier_chain_register(&exit_task_notifier, n);
@@ -91,8 +82,6 @@
break;
}

- up_write(&profile_rwsem);
-
return err;
}

@@ -101,8 +90,6 @@
{
int err = -EINVAL;

- down_write(&profile_rwsem);
-
switch (type) {
case EXIT_TASK:
err = notifier_chain_unregister(&exit_task_notifier, n);
@@ -115,7 +102,6 @@
break;
}

- up_write(&profile_rwsem);
return err;
}