diff options
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 99411bf9d901..09803d0d5207 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -1353,23 +1353,35 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct | |||
1353 | return limit; | 1353 | return limit; |
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | static struct drbd_request *find_oldest_request(struct drbd_connection *connection) | 1356 | static void find_oldest_requests( |
1357 | struct drbd_connection *connection, | ||
1358 | struct drbd_device *device, | ||
1359 | struct drbd_request **oldest_req_waiting_for_peer, | ||
1360 | struct drbd_request **oldest_req_waiting_for_disk) | ||
1357 | { | 1361 | { |
1358 | /* Walk the transfer log, | ||
1359 | * and find the oldest not yet completed request */ | ||
1360 | struct drbd_request *r; | 1362 | struct drbd_request *r; |
1363 | *oldest_req_waiting_for_peer = NULL; | ||
1364 | *oldest_req_waiting_for_disk = NULL; | ||
1361 | list_for_each_entry(r, &connection->transfer_log, tl_requests) { | 1365 | list_for_each_entry(r, &connection->transfer_log, tl_requests) { |
1362 | if (atomic_read(&r->completion_ref)) | 1366 | const unsigned s = r->rq_state; |
1363 | return r; | 1367 | if (!*oldest_req_waiting_for_peer |
1368 | && ((s & RQ_NET_MASK) && !(s & RQ_NET_DONE))) | ||
1369 | *oldest_req_waiting_for_peer = r; | ||
1370 | |||
1371 | if (!*oldest_req_waiting_for_disk | ||
1372 | && (s & RQ_LOCAL_PENDING) && r->device == device) | ||
1373 | *oldest_req_waiting_for_disk = r; | ||
1374 | |||
1375 | if (*oldest_req_waiting_for_peer && *oldest_req_waiting_for_disk) | ||
1376 | break; | ||
1364 | } | 1377 | } |
1365 | return NULL; | ||
1366 | } | 1378 | } |
1367 | 1379 | ||
1368 | void request_timer_fn(unsigned long data) | 1380 | void request_timer_fn(unsigned long data) |
1369 | { | 1381 | { |
1370 | struct drbd_device *device = (struct drbd_device *) data; | 1382 | struct drbd_device *device = (struct drbd_device *) data; |
1371 | struct drbd_connection *connection = first_peer_device(device)->connection; | 1383 | struct drbd_connection *connection = first_peer_device(device)->connection; |
1372 | struct drbd_request *req; /* oldest request */ | 1384 | struct drbd_request *req_disk, *req_peer; /* oldest request */ |
1373 | struct net_conf *nc; | 1385 | struct net_conf *nc; |
1374 | unsigned long ent = 0, dt = 0, et, nt; /* effective timeout = ko_count * timeout */ | 1386 | unsigned long ent = 0, dt = 0, et, nt; /* effective timeout = ko_count * timeout */ |
1375 | unsigned long now; | 1387 | unsigned long now; |
@@ -1393,8 +1405,8 @@ void request_timer_fn(unsigned long data) | |||
1393 | now = jiffies; | 1405 | now = jiffies; |
1394 | 1406 | ||
1395 | spin_lock_irq(&device->resource->req_lock); | 1407 | spin_lock_irq(&device->resource->req_lock); |
1396 | req = find_oldest_request(connection); | 1408 | find_oldest_requests(connection, device, &req_peer, &req_disk); |
1397 | if (!req) { | 1409 | if (req_peer == NULL && req_disk == NULL) { |
1398 | spin_unlock_irq(&device->resource->req_lock); | 1410 | spin_unlock_irq(&device->resource->req_lock); |
1399 | mod_timer(&device->request_timer, now + et); | 1411 | mod_timer(&device->request_timer, now + et); |
1400 | return; | 1412 | return; |
@@ -1416,19 +1428,26 @@ void request_timer_fn(unsigned long data) | |||
1416 | * ~198 days with 250 HZ, we have a window where the timeout would need | 1428 | * ~198 days with 250 HZ, we have a window where the timeout would need |
1417 | * to expire twice (worst case) to become effective. Good enough. | 1429 | * to expire twice (worst case) to become effective. Good enough. |
1418 | */ | 1430 | */ |
1419 | if (ent && req->rq_state & RQ_NET_PENDING && | 1431 | if (ent && req_peer && |
1420 | time_after(now, req->start_time + ent) && | 1432 | time_after(now, req_peer->start_time + ent) && |
1421 | !time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent)) { | 1433 | !time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent)) { |
1422 | drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n"); | 1434 | drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n"); |
1423 | _drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL); | 1435 | _drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL); |
1424 | } | 1436 | } |
1425 | if (dt && req->rq_state & RQ_LOCAL_PENDING && req->device == device && | 1437 | if (dt && req_disk && |
1426 | time_after(now, req->start_time + dt) && | 1438 | time_after(now, req_disk->start_time + dt) && |
1427 | !time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) { | 1439 | !time_in_range(now, device->last_reattach_jif, device->last_reattach_jif + dt)) { |
1428 | drbd_warn(device, "Local backing device failed to meet the disk-timeout\n"); | 1440 | drbd_warn(device, "Local backing device failed to meet the disk-timeout\n"); |
1429 | __drbd_chk_io_error(device, DRBD_FORCE_DETACH); | 1441 | __drbd_chk_io_error(device, DRBD_FORCE_DETACH); |
1430 | } | 1442 | } |
1431 | nt = (time_after(now, req->start_time + et) ? now : req->start_time) + et; | 1443 | |
1444 | /* Reschedule timer for the nearest not already expired timeout. | ||
1445 | * Fallback to now + min(effective network timeout, disk timeout). */ | ||
1446 | ent = (ent && req_peer && time_before(now, req_peer->start_time + ent)) | ||
1447 | ? req_peer->start_time + ent : now + et; | ||
1448 | dt = (dt && req_disk && time_before(now, req_disk->start_time + dt)) | ||
1449 | ? req_disk->start_time + dt : now + et; | ||
1450 | nt = time_before(ent, dt) ? ent : dt; | ||
1432 | spin_unlock_irq(&connection->resource->req_lock); | 1451 | spin_unlock_irq(&connection->resource->req_lock); |
1433 | mod_timer(&device->request_timer, nt); | 1452 | mod_timer(&device->request_timer, nt); |
1434 | } | 1453 | } |