summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_worker.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2014-01-31 14:55:12 +0100
committerPhilipp Reisner <philipp.reisner@linbit.com>2014-07-10 18:35:04 +0200
commit506afb6248af577eb702c73f3da52a12f4c56a38 (patch)
treed4339c873049cff5224e3b449ae8c6c1b8ed3357 /drivers/block/drbd/drbd_worker.c
parent659b2e3bb8b149f5f7e2f8551599044b715bcc21 (diff)
downloadlinux-stable-506afb6248af577eb702c73f3da52a12f4c56a38.tar.gz
linux-stable-506afb6248af577eb702c73f3da52a12f4c56a38.tar.bz2
linux-stable-506afb6248af577eb702c73f3da52a12f4c56a38.zip
drbd: improve resync request throttling due to sendbuf size
If we throttle resync because the socket sendbuffer is filling up, tell TCP about it, so it may expand the sendbuffer for us. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_worker.c')
-rw-r--r--drivers/block/drbd/drbd_worker.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 6532a697cf49..0b5e4294acf9 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -592,7 +592,7 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
const sector_t capacity = drbd_get_capacity(device->this_bdev);
int max_bio_size;
int number, rollback_i, size;
- int align, queued, sndbuf;
+ int align, requeue = 0;
int i = 0;
if (unlikely(cancel))
@@ -619,17 +619,22 @@ static int make_resync_request(struct drbd_device *const device, int cancel)
goto requeue;
for (i = 0; i < number; i++) {
- /* Stop generating RS requests, when half of the send buffer is filled */
+ /* Stop generating RS requests when half of the send buffer is filled,
+ * but notify TCP that we'd like to have more space. */
mutex_lock(&connection->data.mutex);
if (connection->data.socket) {
- queued = connection->data.socket->sk->sk_wmem_queued;
- sndbuf = connection->data.socket->sk->sk_sndbuf;
- } else {
- queued = 1;
- sndbuf = 0;
- }
+ struct sock *sk = connection->data.socket->sk;
+ int queued = sk->sk_wmem_queued;
+ int sndbuf = sk->sk_sndbuf;
+ if (queued > sndbuf / 2) {
+ requeue = 1;
+ if (sk->sk_socket)
+ set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+ }
+ } else
+ requeue = 1;
mutex_unlock(&connection->data.mutex);
- if (queued > sndbuf / 2)
+ if (requeue)
goto requeue;
next_sector: