summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-kcopyd.c
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2011-05-29 14:03:02 +0200
committerAlasdair G Kergon <agk@redhat.com>2011-05-29 14:03:02 +0200
commit4cc1b4cffd187a5c5d6264c8d766c49b3c57fb05 (patch)
tree98b550b7e3c00fcdf20cc8b0a9c5b9478cb45ac9 /drivers/md/dm-kcopyd.c
parentdm kcopyd: preallocate sub jobs to avoid deadlock (diff)
downloadlinux-4cc1b4cffd187a5c5d6264c8d766c49b3c57fb05.tar.xz
linux-4cc1b4cffd187a5c5d6264c8d766c49b3c57fb05.zip
dm kcopyd: remove superfluous page allocation spinlock
Remove the spinlock protecting the pages allocation. The spinlock is only taken on initialization or from single-threaded workqueue. Therefore, the spinlock is useless. The spinlock is taken in kcopyd_get_pages and kcopyd_put_pages. kcopyd_get_pages is only called from run_pages_job, which is only called from process_jobs called from do_work. kcopyd_put_pages is called from client_alloc_pages (which is initialization function) or from run_complete_job. run_complete_job is only called from process_jobs called from do_work. Another spinlock, kc->job_lock is taken each time someone pushes or pops some work for the worker thread. Once we take kc->job_lock, we guarantee that any written memory is visible to the other CPUs. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-kcopyd.c')
-rw-r--r--drivers/md/dm-kcopyd.c11
1 files changed, 1 insertions, 10 deletions
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 24fb42ed7b8e..ed9577916399 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -36,7 +36,6 @@
* pages for kcopyd io.
*---------------------------------------------------------------*/
struct dm_kcopyd_client {
- spinlock_t lock;
struct page_list *pages;
unsigned int nr_pages;
unsigned int nr_free_pages;
@@ -99,11 +98,8 @@ static int kcopyd_get_pages(struct dm_kcopyd_client *kc,
{
struct page_list *pl;
- spin_lock(&kc->lock);
- if (kc->nr_free_pages < nr) {
- spin_unlock(&kc->lock);
+ if (kc->nr_free_pages < nr)
return -ENOMEM;
- }
kc->nr_free_pages -= nr;
for (*pages = pl = kc->pages; --nr; pl = pl->next)
@@ -112,8 +108,6 @@ static int kcopyd_get_pages(struct dm_kcopyd_client *kc,
kc->pages = pl->next;
pl->next = NULL;
- spin_unlock(&kc->lock);
-
return 0;
}
@@ -121,14 +115,12 @@ static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl)
{
struct page_list *cursor;
- spin_lock(&kc->lock);
for (cursor = pl; cursor->next; cursor = cursor->next)
kc->nr_free_pages++;
kc->nr_free_pages++;
cursor->next = kc->pages;
kc->pages = pl;
- spin_unlock(&kc->lock);
}
/*
@@ -625,7 +617,6 @@ int dm_kcopyd_client_create(unsigned int nr_pages,
if (!kc)
return -ENOMEM;
- spin_lock_init(&kc->lock);
spin_lock_init(&kc->job_lock);
INIT_LIST_HEAD(&kc->complete_jobs);
INIT_LIST_HEAD(&kc->io_jobs);