Commit f649d6d3 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Linus Torvalds
Browse files

proc: simplify locking in remove_proc_entry()



proc_subdir_lock protects only modifying and walking through PDE lists, so
after we've found PDE to remove and actually removed it from lists, there is
no need to hold proc_subdir_lock for the rest of operation.

Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 638fa202
Loading
Loading
Loading
Loading
+40 −42
Original line number Diff line number Diff line
@@ -734,21 +734,26 @@ void free_proc_entry(struct proc_dir_entry *de)
void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
{
	struct proc_dir_entry **p;
	struct proc_dir_entry *de;
	struct proc_dir_entry *de = NULL;
	const char *fn = name;
	int len;

	if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
		goto out;
		return;
	len = strlen(fn);

	spin_lock(&proc_subdir_lock);
	for (p = &parent->subdir; *p; p=&(*p)->next ) {
		if (!proc_match(len, fn, *p))
			continue;
		if (proc_match(len, fn, *p)) {
			de = *p;
			*p = de->next;
			de->next = NULL;
			break;
		}
	}
	spin_unlock(&proc_subdir_lock);
	if (!de)
		return;

	spin_lock(&de->pde_unload_lock);
	/*
@@ -764,11 +769,9 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
			de->pde_unload_completion = &c;

		spin_unlock(&de->pde_unload_lock);
			spin_unlock(&proc_subdir_lock);

		wait_for_completion(de->pde_unload_completion);

			spin_lock(&proc_subdir_lock);
		goto continue_removing;
	}
	spin_unlock(&de->pde_unload_lock);
@@ -785,9 +788,4 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
	}
	if (atomic_dec_and_test(&de->count))
		free_proc_entry(de);
		break;
	}
	spin_unlock(&proc_subdir_lock);
out:
	return;
}