diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2010-10-29 23:32:01 +0200 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-11-27 19:50:43 +0100 |
commit | c13f7e1a94007c4381814e7daf033e3e8f0663f3 (patch) | |
tree | 38115a45b39cd53204268238b8dc6e5bbfd9bafc /drivers/block | |
parent | 19650e8580987c0ffabc2fe2cbc16b944789df8b (diff) | |
download | linux-c13f7e1a94007c4381814e7daf033e3e8f0663f3.tar.bz2 |
drbd: don't recvmsg with zero length
This should fix a performance degradation we observed recently.
If we don't expect any subheader, we should not call into the tcp stack,
as that may add considerable latency if there is no data available at
this point.
For a synthetic synchronous write load with single outstanding writes,
this additional latency when processing the "unplug remote" packet
added up to a performance degradation factor >= 10.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 89d8a7cc4054..24487d4fb202 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3627,17 +3627,19 @@ static void drbdd(struct drbd_conf *mdev) } shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header); - rv = drbd_recv(mdev, &header->h80.payload, shs); - if (unlikely(rv != shs)) { - dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); - goto err_out; - } - if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) { dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size); goto err_out; } + if (shs) { + rv = drbd_recv(mdev, &header->h80.payload, shs); + if (unlikely(rv != shs)) { + dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); + goto err_out; + } + } + rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs); if (unlikely(!rv)) { |