aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-02-21 11:10:06 -0500
committerAlex Elder <elder@inktank.com>2013-02-25 16:36:50 -0500
commit632b88cadece050ca925d74bda250c4a320c5cc7 (patch)
treecd99c51628ae8ca73fdc34674f139d516215c61d
parent4dda41d3d76747414586a4bad5615b550e0986b1 (diff)
rbd: barriers are hard
Let's go shopping! I'm afraid this may not have gotten it right: 07741308 rbd: add barriers near done flag operations The smp_wmb() should have been done *before* setting the done flag, to ensure all other data was valid before marking the object request done. Switch to use atomic_inc_return() here to set the done flag, which allows us to verify we don't mark something done more than once. Doing this also implies general barriers before and after the call. And although a read memory barrier might have been sufficient before reading the done flag, convert this to a full memory barrier just to put this issue to bed. This resolves: http://tracker.ceph.com/issues/4238 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--drivers/block/rbd.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 3cc003b26610..bd6078bf99d3 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1226,13 +1226,22 @@ static void obj_request_done_init(struct rbd_obj_request *obj_request)
1226 1226
1227static void obj_request_done_set(struct rbd_obj_request *obj_request) 1227static void obj_request_done_set(struct rbd_obj_request *obj_request)
1228{ 1228{
1229 atomic_set(&obj_request->done, 1); 1229 int done;
1230 smp_wmb(); 1230
1231 done = atomic_inc_return(&obj_request->done);
1232 if (done > 1) {
1233 struct rbd_img_request *img_request = obj_request->img_request;
1234 struct rbd_device *rbd_dev;
1235
1236 rbd_dev = img_request ? img_request->rbd_dev : NULL;
1237 rbd_warn(rbd_dev, "obj_request %p was already done\n",
1238 obj_request);
1239 }
1231} 1240}
1232 1241
1233static bool obj_request_done_test(struct rbd_obj_request *obj_request) 1242static bool obj_request_done_test(struct rbd_obj_request *obj_request)
1234{ 1243{
1235 smp_rmb(); 1244 smp_mb();
1236 return atomic_read(&obj_request->done) != 0; 1245 return atomic_read(&obj_request->done) != 0;
1237} 1246}
1238 1247