diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-09-21 08:12:53 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-12-14 10:33:38 -0500 |
commit | 9af3e04ee41e6841b2accb9dc96562bcf4e59916 (patch) | |
tree | 96bedbba070cc7d46a1470b1de0248bd3447a9b5 | |
parent | 0db78559f965a2e652dbe8acf35333f2081bf872 (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.c | 34 |
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 | */ |
92 | static void ap_tasklet_fn(unsigned long); | 92 | static void ap_tasklet_fn(unsigned long); |
93 | static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0); | 93 | static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0); |
94 | static atomic_t ap_poll_requests = ATOMIC_INIT(0); | ||
95 | static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait); | 94 | static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait); |
96 | static struct task_struct *ap_poll_kthread = NULL; | 95 | static struct task_struct *ap_poll_kthread = NULL; |
97 | static DEFINE_MUTEX(ap_poll_thread_mutex); | 96 | static 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 | ||
795 | static 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 | ||