aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r--drivers/block/drbd/drbd_req.c47
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
1356static struct drbd_request *find_oldest_request(struct drbd_connection *connection) 1356static 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
1368void request_timer_fn(unsigned long data) 1380void 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}