diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2011-05-29 08:03:02 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2011-05-29 08:03:02 -0400 |
commit | 4cc1b4cffd187a5c5d6264c8d766c49b3c57fb05 (patch) | |
tree | 98b550b7e3c00fcdf20cc8b0a9c5b9478cb45ac9 /drivers/md | |
parent | c6ea41fbbe08f270a8edef99dc369faf809d1bd6 (diff) |
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')
-rw-r--r-- | drivers/md/dm-kcopyd.c | 11 |
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 @@ | |||
36 | * pages for kcopyd io. | 36 | * pages for kcopyd io. |
37 | *---------------------------------------------------------------*/ | 37 | *---------------------------------------------------------------*/ |
38 | struct dm_kcopyd_client { | 38 | struct dm_kcopyd_client { |
39 | spinlock_t lock; | ||
40 | struct page_list *pages; | 39 | struct page_list *pages; |
41 | unsigned int nr_pages; | 40 | unsigned int nr_pages; |
42 | unsigned int nr_free_pages; | 41 | unsigned int nr_free_pages; |
@@ -99,11 +98,8 @@ static int kcopyd_get_pages(struct dm_kcopyd_client *kc, | |||
99 | { | 98 | { |
100 | struct page_list *pl; | 99 | struct page_list *pl; |
101 | 100 | ||
102 | spin_lock(&kc->lock); | 101 | if (kc->nr_free_pages < nr) |
103 | if (kc->nr_free_pages < nr) { | ||
104 | spin_unlock(&kc->lock); | ||
105 | return -ENOMEM; | 102 | return -ENOMEM; |
106 | } | ||
107 | 103 | ||
108 | kc->nr_free_pages -= nr; | 104 | kc->nr_free_pages -= nr; |
109 | for (*pages = pl = kc->pages; --nr; pl = pl->next) | 105 | for (*pages = pl = kc->pages; --nr; pl = pl->next) |
@@ -112,8 +108,6 @@ static int kcopyd_get_pages(struct dm_kcopyd_client *kc, | |||
112 | kc->pages = pl->next; | 108 | kc->pages = pl->next; |
113 | pl->next = NULL; | 109 | pl->next = NULL; |
114 | 110 | ||
115 | spin_unlock(&kc->lock); | ||
116 | |||
117 | return 0; | 111 | return 0; |
118 | } | 112 | } |
119 | 113 | ||
@@ -121,14 +115,12 @@ static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) | |||
121 | { | 115 | { |
122 | struct page_list *cursor; | 116 | struct page_list *cursor; |
123 | 117 | ||
124 | spin_lock(&kc->lock); | ||
125 | for (cursor = pl; cursor->next; cursor = cursor->next) | 118 | for (cursor = pl; cursor->next; cursor = cursor->next) |
126 | kc->nr_free_pages++; | 119 | kc->nr_free_pages++; |
127 | 120 | ||
128 | kc->nr_free_pages++; | 121 | kc->nr_free_pages++; |
129 | cursor->next = kc->pages; | 122 | cursor->next = kc->pages; |
130 | kc->pages = pl; | 123 | kc->pages = pl; |
131 | spin_unlock(&kc->lock); | ||
132 | } | 124 | } |
133 | 125 | ||
134 | /* | 126 | /* |
@@ -625,7 +617,6 @@ int dm_kcopyd_client_create(unsigned int nr_pages, | |||
625 | if (!kc) | 617 | if (!kc) |
626 | return -ENOMEM; | 618 | return -ENOMEM; |
627 | 619 | ||
628 | spin_lock_init(&kc->lock); | ||
629 | spin_lock_init(&kc->job_lock); | 620 | spin_lock_init(&kc->job_lock); |
630 | INIT_LIST_HEAD(&kc->complete_jobs); | 621 | INIT_LIST_HEAD(&kc->complete_jobs); |
631 | INIT_LIST_HEAD(&kc->io_jobs); | 622 | INIT_LIST_HEAD(&kc->io_jobs); |