aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-02-06 00:41:50 -0500
committerSage Weil <sage@inktank.com>2013-02-13 21:29:11 -0500
commit077413082f9ade9ca4d9774dbdc81ee7256d8089 (patch)
tree825678f1ad0b9108bb2beb7e6f1e29415d49d27c /drivers/block
parenta14ea269dd6b5e48a2941ba73b202cd7cd5d716d (diff)
rbd: add barriers near done flag operations
Somehow, I missed this little item in Documentation/atomic_ops.txt: *** WARNING: atomic_read() and atomic_set() DO NOT IMPLY BARRIERS! *** Create and use some helper functions that include the proper memory barriers for manipulating the done field. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 91983a60487b..982963ec2607 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1216,10 +1216,28 @@ static int rbd_obj_request_wait(struct rbd_obj_request *obj_request)
1216 return wait_for_completion_interruptible(&obj_request->completion); 1216 return wait_for_completion_interruptible(&obj_request->completion);
1217} 1217}
1218 1218
1219static void obj_request_done_init(struct rbd_obj_request *obj_request)
1220{
1221 atomic_set(&obj_request->done, 0);
1222 smp_wmb();
1223}
1224
1225static void obj_request_done_set(struct rbd_obj_request *obj_request)
1226{
1227 atomic_set(&obj_request->done, 1);
1228 smp_wmb();
1229}
1230
1231static bool obj_request_done_test(struct rbd_obj_request *obj_request)
1232{
1233 smp_rmb();
1234 return atomic_read(&obj_request->done) != 0;
1235}
1236
1219static void rbd_osd_trivial_callback(struct rbd_obj_request *obj_request, 1237static void rbd_osd_trivial_callback(struct rbd_obj_request *obj_request,
1220 struct ceph_osd_op *op) 1238 struct ceph_osd_op *op)
1221{ 1239{
1222 atomic_set(&obj_request->done, 1); 1240 obj_request_done_set(obj_request);
1223} 1241}
1224 1242
1225static void rbd_obj_request_complete(struct rbd_obj_request *obj_request) 1243static void rbd_obj_request_complete(struct rbd_obj_request *obj_request)
@@ -1249,14 +1267,14 @@ static void rbd_osd_read_callback(struct rbd_obj_request *obj_request,
1249 xferred = obj_request->length; 1267 xferred = obj_request->length;
1250 } 1268 }
1251 obj_request->xferred = xferred; 1269 obj_request->xferred = xferred;
1252 atomic_set(&obj_request->done, 1); 1270 obj_request_done_set(obj_request);
1253} 1271}
1254 1272
1255static void rbd_osd_write_callback(struct rbd_obj_request *obj_request, 1273static void rbd_osd_write_callback(struct rbd_obj_request *obj_request,
1256 struct ceph_osd_op *op) 1274 struct ceph_osd_op *op)
1257{ 1275{
1258 obj_request->xferred = le64_to_cpu(op->extent.length); 1276 obj_request->xferred = le64_to_cpu(op->extent.length);
1259 atomic_set(&obj_request->done, 1); 1277 obj_request_done_set(obj_request);
1260} 1278}
1261 1279
1262static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, 1280static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
@@ -1300,7 +1318,7 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
1300 break; 1318 break;
1301 } 1319 }
1302 1320
1303 if (atomic_read(&obj_request->done)) 1321 if (obj_request_done_test(obj_request))
1304 rbd_obj_request_complete(obj_request); 1322 rbd_obj_request_complete(obj_request);
1305} 1323}
1306 1324
@@ -1407,7 +1425,7 @@ static struct rbd_obj_request *rbd_obj_request_create(const char *object_name,
1407 obj_request->which = BAD_WHICH; 1425 obj_request->which = BAD_WHICH;
1408 obj_request->type = type; 1426 obj_request->type = type;
1409 INIT_LIST_HEAD(&obj_request->links); 1427 INIT_LIST_HEAD(&obj_request->links);
1410 atomic_set(&obj_request->done, 0); 1428 obj_request_done_init(obj_request);
1411 init_completion(&obj_request->completion); 1429 init_completion(&obj_request->completion);
1412 kref_init(&obj_request->kref); 1430 kref_init(&obj_request->kref);
1413 1431
@@ -1611,7 +1629,7 @@ static void rbd_img_obj_callback(struct rbd_obj_request *obj_request)
1611 rbd_assert(more); 1629 rbd_assert(more);
1612 rbd_assert(which < img_request->obj_request_count); 1630 rbd_assert(which < img_request->obj_request_count);
1613 1631
1614 if (!atomic_read(&obj_request->done)) 1632 if (!obj_request_done_test(obj_request))
1615 break; 1633 break;
1616 1634
1617 rbd_assert(obj_request->xferred <= (u64) UINT_MAX); 1635 rbd_assert(obj_request->xferred <= (u64) UINT_MAX);