aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2016-09-21 08:12:53 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-12-14 10:33:38 -0500
commit9af3e04ee41e6841b2accb9dc96562bcf4e59916 (patch)
tree96bedbba070cc7d46a1470b1de0248bd3447a9b5
parent0db78559f965a2e652dbe8acf35333f2081bf872 (diff)
s390/zcrypt: get rid of ap_poll_requests
The poll thread of the AP bus is burning CPU while waiting for crypto requests to complete. We can as well burn a few more cycles in the poll thread to check if there are pending requests and remove the atomic operations with the ap_poll_requests. This improves the code if the machine has adapter interrupts. Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/crypto/ap_bus.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index f6de22a4f7d9..fe1cfa4b22c9 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -91,7 +91,6 @@ static DECLARE_WORK(ap_scan_work, ap_scan_bus);
91 */ 91 */
92static void ap_tasklet_fn(unsigned long); 92static void ap_tasklet_fn(unsigned long);
93static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0); 93static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0);
94static atomic_t ap_poll_requests = ATOMIC_INIT(0);
95static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait); 94static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
96static struct task_struct *ap_poll_kthread = NULL; 95static struct task_struct *ap_poll_kthread = NULL;
97static DEFINE_MUTEX(ap_poll_thread_mutex); 96static DEFINE_MUTEX(ap_poll_thread_mutex);
@@ -419,7 +418,6 @@ static struct ap_queue_status ap_sm_recv(struct ap_device *ap_dev)
419 ap_dev->reply->message, ap_dev->reply->length); 418 ap_dev->reply->message, ap_dev->reply->length);
420 switch (status.response_code) { 419 switch (status.response_code) {
421 case AP_RESPONSE_NORMAL: 420 case AP_RESPONSE_NORMAL:
422 atomic_dec(&ap_poll_requests);
423 ap_dev->queue_count--; 421 ap_dev->queue_count--;
424 if (ap_dev->queue_count > 0) 422 if (ap_dev->queue_count > 0)
425 mod_timer(&ap_dev->timeout, 423 mod_timer(&ap_dev->timeout,
@@ -436,7 +434,6 @@ static struct ap_queue_status ap_sm_recv(struct ap_device *ap_dev)
436 if (!status.queue_empty || ap_dev->queue_count <= 0) 434 if (!status.queue_empty || ap_dev->queue_count <= 0)
437 break; 435 break;
438 /* The card shouldn't forget requests but who knows. */ 436 /* The card shouldn't forget requests but who knows. */
439 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
440 ap_dev->queue_count = 0; 437 ap_dev->queue_count = 0;
441 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); 438 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
442 ap_dev->requestq_count += ap_dev->pendingq_count; 439 ap_dev->requestq_count += ap_dev->pendingq_count;
@@ -524,7 +521,6 @@ static enum ap_wait ap_sm_write(struct ap_device *ap_dev)
524 ap_msg->message, ap_msg->length, ap_msg->special); 521 ap_msg->message, ap_msg->length, ap_msg->special);
525 switch (status.response_code) { 522 switch (status.response_code) {
526 case AP_RESPONSE_NORMAL: 523 case AP_RESPONSE_NORMAL:
527 atomic_inc(&ap_poll_requests);
528 ap_dev->queue_count++; 524 ap_dev->queue_count++;
529 if (ap_dev->queue_count == 1) 525 if (ap_dev->queue_count == 1)
530 mod_timer(&ap_dev->timeout, 526 mod_timer(&ap_dev->timeout,
@@ -796,6 +792,27 @@ static void ap_tasklet_fn(unsigned long dummy)
796 ap_sm_wait(wait); 792 ap_sm_wait(wait);
797} 793}
798 794
795static int ap_pending_requests(void)
796{
797 struct ap_device *ap_dev;
798 int id, pending = 0;
799
800 for (id = 0; pending == 0 && id < AP_DEVICES; id++) {
801 spin_lock_bh(&ap_device_list_lock);
802 list_for_each_entry(ap_dev, &ap_device_list, list) {
803 spin_lock_bh(&ap_dev->lock);
804 if (ap_dev->queue_count)
805 pending = 1;
806 spin_unlock_bh(&ap_dev->lock);
807 if (pending)
808 break;
809 }
810 spin_unlock_bh(&ap_device_list_lock);
811 }
812
813 return pending;
814}
815
799/** 816/**
800 * ap_poll_thread(): Thread that polls for finished requests. 817 * ap_poll_thread(): Thread that polls for finished requests.
801 * @data: Unused pointer 818 * @data: Unused pointer
@@ -815,8 +832,7 @@ static int ap_poll_thread(void *data)
815 while (!kthread_should_stop()) { 832 while (!kthread_should_stop()) {
816 add_wait_queue(&ap_poll_wait, &wait); 833 add_wait_queue(&ap_poll_wait, &wait);
817 set_current_state(TASK_INTERRUPTIBLE); 834 set_current_state(TASK_INTERRUPTIBLE);
818 if (ap_suspend_flag || 835 if (ap_suspend_flag || !ap_pending_requests()) {
819 atomic_read(&ap_poll_requests) <= 0) {
820 schedule(); 836 schedule();
821 try_to_freeze(); 837 try_to_freeze();
822 } 838 }
@@ -828,7 +844,8 @@ static int ap_poll_thread(void *data)
828 continue; 844 continue;
829 } 845 }
830 ap_tasklet_fn(0); 846 ap_tasklet_fn(0);
831 } while (!kthread_should_stop()); 847 }
848
832 return 0; 849 return 0;
833} 850}
834 851
@@ -1267,9 +1284,6 @@ static int ap_device_remove(struct device *dev)
1267 spin_unlock_bh(&ap_device_list_lock); 1284 spin_unlock_bh(&ap_device_list_lock);
1268 if (ap_drv->remove) 1285 if (ap_drv->remove)
1269 ap_drv->remove(ap_dev); 1286 ap_drv->remove(ap_dev);
1270 spin_lock_bh(&ap_dev->lock);
1271 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1272 spin_unlock_bh(&ap_dev->lock);
1273 return 0; 1287 return 0;
1274} 1288}
1275 1289