aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Pau Monne <roger.pau@citrix.com>2013-03-18 12:49:34 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2013-03-19 10:27:56 -0400
commit155b7edb51430a280f86c1e21b7be308b0d219d4 (patch)
tree9e4d66a3da12ecc42a8e2dc84460264087a2b0b1
parent217fd5e709f029c125a9d39de5f13387407f131a (diff)
xen-blkfront: switch from llist to list
The git commit f84adf4921ae3115502f44ff467b04bf2f88cf04 (xen-blkfront: drop the use of llist_for_each_entry_safe) was a stop-gate to fix a GCC4.1 bug. The appropiate way is to actually use an list instead of using an llist. As such this patch replaces the usage of llist with an list. Since we always manipulate the list while holding the io_lock, there's no need for additional locking (llist used previously is safe to use concurrently without additional locking). Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> CC: stable@vger.kernel.org [v1: Redid the git commit description] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--drivers/block/xen-blkfront.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 962064487ef7..97324cd18f4b 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -44,7 +44,7 @@
44#include <linux/mutex.h> 44#include <linux/mutex.h>
45#include <linux/scatterlist.h> 45#include <linux/scatterlist.h>
46#include <linux/bitmap.h> 46#include <linux/bitmap.h>
47#include <linux/llist.h> 47#include <linux/list.h>
48 48
49#include <xen/xen.h> 49#include <xen/xen.h>
50#include <xen/xenbus.h> 50#include <xen/xenbus.h>
@@ -68,7 +68,7 @@ enum blkif_state {
68struct grant { 68struct grant {
69 grant_ref_t gref; 69 grant_ref_t gref;
70 unsigned long pfn; 70 unsigned long pfn;
71 struct llist_node node; 71 struct list_head node;
72}; 72};
73 73
74struct blk_shadow { 74struct blk_shadow {
@@ -105,7 +105,7 @@ struct blkfront_info
105 struct work_struct work; 105 struct work_struct work;
106 struct gnttab_free_callback callback; 106 struct gnttab_free_callback callback;
107 struct blk_shadow shadow[BLK_RING_SIZE]; 107 struct blk_shadow shadow[BLK_RING_SIZE];
108 struct llist_head persistent_gnts; 108 struct list_head persistent_gnts;
109 unsigned int persistent_gnts_c; 109 unsigned int persistent_gnts_c;
110 unsigned long shadow_free; 110 unsigned long shadow_free;
111 unsigned int feature_flush; 111 unsigned int feature_flush;
@@ -371,10 +371,11 @@ static int blkif_queue_request(struct request *req)
371 lsect = fsect + (sg->length >> 9) - 1; 371 lsect = fsect + (sg->length >> 9) - 1;
372 372
373 if (info->persistent_gnts_c) { 373 if (info->persistent_gnts_c) {
374 BUG_ON(llist_empty(&info->persistent_gnts)); 374 BUG_ON(list_empty(&info->persistent_gnts));
375 gnt_list_entry = llist_entry( 375 gnt_list_entry = list_first_entry(
376 llist_del_first(&info->persistent_gnts), 376 &info->persistent_gnts,
377 struct grant, node); 377 struct grant, node);
378 list_del(&gnt_list_entry->node);
378 379
379 ref = gnt_list_entry->gref; 380 ref = gnt_list_entry->gref;
380 buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); 381 buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
@@ -790,9 +791,8 @@ static void blkif_restart_queue(struct work_struct *work)
790 791
791static void blkif_free(struct blkfront_info *info, int suspend) 792static void blkif_free(struct blkfront_info *info, int suspend)
792{ 793{
793 struct llist_node *all_gnts; 794 struct grant *persistent_gnt;
794 struct grant *persistent_gnt, *tmp; 795 struct grant *n;
795 struct llist_node *n;
796 796
797 /* Prevent new requests being issued until we fix things up. */ 797 /* Prevent new requests being issued until we fix things up. */
798 spin_lock_irq(&info->io_lock); 798 spin_lock_irq(&info->io_lock);
@@ -804,20 +804,15 @@ static void blkif_free(struct blkfront_info *info, int suspend)
804 804
805 /* Remove all persistent grants */ 805 /* Remove all persistent grants */
806 if (info->persistent_gnts_c) { 806 if (info->persistent_gnts_c) {
807 all_gnts = llist_del_all(&info->persistent_gnts); 807 list_for_each_entry_safe(persistent_gnt, n,
808 persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node); 808 &info->persistent_gnts, node) {
809 while (persistent_gnt) { 809 list_del(&persistent_gnt->node);
810 gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); 810 gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
811 __free_page(pfn_to_page(persistent_gnt->pfn)); 811 __free_page(pfn_to_page(persistent_gnt->pfn));
812 tmp = persistent_gnt; 812 kfree(persistent_gnt);
813 n = persistent_gnt->node.next; 813 info->persistent_gnts_c--;
814 if (n)
815 persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node);
816 else
817 persistent_gnt = NULL;
818 kfree(tmp);
819 } 814 }
820 info->persistent_gnts_c = 0; 815 BUG_ON(info->persistent_gnts_c != 0);
821 } 816 }
822 817
823 /* No more gnttab callback work. */ 818 /* No more gnttab callback work. */
@@ -875,7 +870,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
875 } 870 }
876 /* Add the persistent grant into the list of free grants */ 871 /* Add the persistent grant into the list of free grants */
877 for (i = 0; i < s->req.u.rw.nr_segments; i++) { 872 for (i = 0; i < s->req.u.rw.nr_segments; i++) {
878 llist_add(&s->grants_used[i]->node, &info->persistent_gnts); 873 list_add(&s->grants_used[i]->node, &info->persistent_gnts);
879 info->persistent_gnts_c++; 874 info->persistent_gnts_c++;
880 } 875 }
881} 876}
@@ -1171,7 +1166,7 @@ static int blkfront_probe(struct xenbus_device *dev,
1171 spin_lock_init(&info->io_lock); 1166 spin_lock_init(&info->io_lock);
1172 info->xbdev = dev; 1167 info->xbdev = dev;
1173 info->vdevice = vdevice; 1168 info->vdevice = vdevice;
1174 init_llist_head(&info->persistent_gnts); 1169 INIT_LIST_HEAD(&info->persistent_gnts);
1175 info->persistent_gnts_c = 0; 1170 info->persistent_gnts_c = 0;
1176 info->connected = BLKIF_STATE_DISCONNECTED; 1171 info->connected = BLKIF_STATE_DISCONNECTED;
1177 INIT_WORK(&info->work, blkif_restart_queue); 1172 INIT_WORK(&info->work, blkif_restart_queue);