Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cifs: smbd: Do not schedule work to send immediate packet on every receive

Immediate packets should only be sent to peer when there are new
receive credits made available. New credits show up on freeing
receive buffer, not on receiving data.

Fix this by avoid unnenecessary work schedules.

Signed-off-by: Long Li <longli@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Long Li and committed by
Steve French
044b541c f1b7b862

+10 -52
+10 -51
fs/cifs/smbdirect.c
··· 380 380 return true; 381 381 } 382 382 383 - /* 384 - * Check and schedule to send an immediate packet 385 - * This is used to extend credtis to remote peer to keep the transport busy 386 - */ 387 - static void check_and_send_immediate(struct smbd_connection *info) 388 - { 389 - if (info->transport_status != SMBD_CONNECTED) 390 - return; 391 - 392 - info->send_immediate = true; 393 - 394 - /* 395 - * Promptly send a packet if our peer is running low on receive 396 - * credits 397 - */ 398 - if (atomic_read(&info->receive_credits) < 399 - info->receive_credit_target - 1) 400 - queue_delayed_work( 401 - info->workqueue, &info->send_immediate_work, 0); 402 - } 403 - 404 383 static void smbd_post_send_credits(struct work_struct *work) 405 384 { 406 385 int ret = 0; ··· 429 450 info->new_credits_offered += ret; 430 451 spin_unlock(&info->lock_new_credits_offered); 431 452 432 - /* Check if we can post new receive and grant credits to peer */ 433 - check_and_send_immediate(info); 453 + /* Promptly send an immediate packet as defined in [MS-SMBD] 3.1.1.1 */ 454 + info->send_immediate = true; 455 + if (atomic_read(&info->receive_credits) < 456 + info->receive_credit_target - 1) { 457 + if (info->keep_alive_requested == KEEP_ALIVE_PENDING || 458 + info->send_immediate) { 459 + log_keep_alive(INFO, "send an empty message\n"); 460 + smbd_post_send_empty(info); 461 + } 462 + } 434 463 } 435 464 436 465 /* Called from softirq, when recv is done */ ··· 532 545 SMB_DIRECT_RESPONSE_REQUESTED) { 533 546 info->keep_alive_requested = KEEP_ALIVE_PENDING; 534 547 } 535 - 536 - /* 537 - * Check if we need to send something to remote peer to 538 - * grant more credits or respond to KEEP_ALIVE packet 539 - */ 540 - check_and_send_immediate(info); 541 548 542 549 return; 543 550 ··· 1292 1311 mempool_free(response, info->response_mempool); 1293 1312 } 1294 1313 1295 - /* 1296 - * Check and send an immediate or keep alive packet 1297 - * The condition to send those packets are defined in [MS-SMBD] 3.1.1.1 1298 - * Connection.KeepaliveRequested and Connection.SendImmediate 1299 - * The idea is to extend credits to server as soon as it becomes available 1300 - */ 1301 - static void send_immediate_work(struct work_struct *work) 1302 - { 1303 - struct smbd_connection *info = container_of( 1304 - work, struct smbd_connection, 1305 - send_immediate_work.work); 1306 - 1307 - if (info->keep_alive_requested == KEEP_ALIVE_PENDING || 1308 - info->send_immediate) { 1309 - log_keep_alive(INFO, "send an empty message\n"); 1310 - smbd_post_send_empty(info); 1311 - } 1312 - } 1313 - 1314 1314 /* Implement idle connection timer [MS-SMBD] 3.1.6.2 */ 1315 1315 static void idle_connection_timer(struct work_struct *work) 1316 1316 { ··· 1346 1384 1347 1385 log_rdma_event(INFO, "cancelling idle timer\n"); 1348 1386 cancel_delayed_work_sync(&info->idle_timer_work); 1349 - log_rdma_event(INFO, "cancelling send immediate work\n"); 1350 - cancel_delayed_work_sync(&info->send_immediate_work); 1351 1387 1352 1388 log_rdma_event(INFO, "wait for all send posted to IB to finish\n"); 1353 1389 wait_event(info->wait_send_pending, ··· 1679 1719 1680 1720 init_waitqueue_head(&info->wait_send_queue); 1681 1721 INIT_DELAYED_WORK(&info->idle_timer_work, idle_connection_timer); 1682 - INIT_DELAYED_WORK(&info->send_immediate_work, send_immediate_work); 1683 1722 queue_delayed_work(info->workqueue, &info->idle_timer_work, 1684 1723 info->keep_alive_interval*HZ); 1685 1724
-1
fs/cifs/smbdirect.h
··· 153 153 154 154 struct workqueue_struct *workqueue; 155 155 struct delayed_work idle_timer_work; 156 - struct delayed_work send_immediate_work; 157 156 158 157 /* Memory pool for preallocating buffers */ 159 158 /* request pool for RDMA send */