mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
s390/zcrypt: Fixed attrition of AP adapters and domains
Currently the first eligible AP adapter respectively domain will be selected to service requests. In case of sequential workload, the very same adapter/domain will be used. The adapter/domain selection algorithm now considers the completed transactions per adaper/domain and therefore ensures a homogeneous utilization. Signed-off-by: Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
b886a9d156
commit
e47de21dd3
@ -195,6 +195,7 @@ struct ap_card {
|
|||||||
unsigned int functions; /* AP device function bitfield. */
|
unsigned int functions; /* AP device function bitfield. */
|
||||||
int queue_depth; /* AP queue depth.*/
|
int queue_depth; /* AP queue depth.*/
|
||||||
int id; /* AP card number. */
|
int id; /* AP card number. */
|
||||||
|
atomic_t total_request_count; /* # requests ever for this AP device.*/
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device)
|
#define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device)
|
||||||
@ -211,7 +212,7 @@ struct ap_queue {
|
|||||||
enum ap_state state; /* State of the AP device. */
|
enum ap_state state; /* State of the AP device. */
|
||||||
int pendingq_count; /* # requests on pendingq list. */
|
int pendingq_count; /* # requests on pendingq list. */
|
||||||
int requestq_count; /* # requests on requestq list. */
|
int requestq_count; /* # requests on requestq list. */
|
||||||
int total_request_count; /* # requests ever for this AP device. */
|
int total_request_count; /* # requests ever for this AP device.*/
|
||||||
int request_timeout; /* Request timout in jiffies. */
|
int request_timeout; /* Request timout in jiffies. */
|
||||||
struct timer_list timeout; /* Timer for request timeouts. */
|
struct timer_list timeout; /* Timer for request timeouts. */
|
||||||
struct list_head pendingq; /* List of message sent to AP queue. */
|
struct list_head pendingq; /* List of message sent to AP queue. */
|
||||||
|
@ -63,13 +63,11 @@ static ssize_t ap_request_count_show(struct device *dev,
|
|||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct ap_card *ac = to_ap_card(dev);
|
struct ap_card *ac = to_ap_card(dev);
|
||||||
struct ap_queue *aq;
|
|
||||||
unsigned int req_cnt;
|
unsigned int req_cnt;
|
||||||
|
|
||||||
req_cnt = 0;
|
req_cnt = 0;
|
||||||
spin_lock_bh(&ap_list_lock);
|
spin_lock_bh(&ap_list_lock);
|
||||||
for_each_ap_queue(aq, ac)
|
req_cnt = atomic_read(&ac->total_request_count);
|
||||||
req_cnt += aq->total_request_count;
|
|
||||||
spin_unlock_bh(&ap_list_lock);
|
spin_unlock_bh(&ap_list_lock);
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
|
return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
|
||||||
}
|
}
|
||||||
|
@ -625,6 +625,7 @@ void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg)
|
|||||||
list_add_tail(&ap_msg->list, &aq->requestq);
|
list_add_tail(&ap_msg->list, &aq->requestq);
|
||||||
aq->requestq_count++;
|
aq->requestq_count++;
|
||||||
aq->total_request_count++;
|
aq->total_request_count++;
|
||||||
|
atomic_inc(&aq->card->total_request_count);
|
||||||
/* Send/receive as many request from the queue as possible. */
|
/* Send/receive as many request from the queue as possible. */
|
||||||
ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL));
|
ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL));
|
||||||
spin_unlock_bh(&aq->lock);
|
spin_unlock_bh(&aq->lock);
|
||||||
|
@ -188,6 +188,34 @@ static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
|
|||||||
module_put(mod);
|
module_put(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
|
||||||
|
struct zcrypt_card *pref_zc,
|
||||||
|
unsigned weight, unsigned pref_weight)
|
||||||
|
{
|
||||||
|
if (!pref_zc)
|
||||||
|
return 0;
|
||||||
|
weight += atomic_read(&zc->load);
|
||||||
|
pref_weight += atomic_read(&pref_zc->load);
|
||||||
|
if (weight == pref_weight)
|
||||||
|
return atomic_read(&zc->card->total_request_count) >
|
||||||
|
atomic_read(&pref_zc->card->total_request_count);
|
||||||
|
return weight > pref_weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool zcrypt_queue_compare(struct zcrypt_queue *zq,
|
||||||
|
struct zcrypt_queue *pref_zq,
|
||||||
|
unsigned weight, unsigned pref_weight)
|
||||||
|
{
|
||||||
|
if (!pref_zq)
|
||||||
|
return 0;
|
||||||
|
weight += atomic_read(&zq->load);
|
||||||
|
pref_weight += atomic_read(&pref_zq->load);
|
||||||
|
if (weight == pref_weight)
|
||||||
|
return &zq->queue->total_request_count >
|
||||||
|
&pref_zq->queue->total_request_count;
|
||||||
|
return weight > pref_weight;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zcrypt ioctls.
|
* zcrypt ioctls.
|
||||||
*/
|
*/
|
||||||
@ -225,15 +253,14 @@ static long zcrypt_rsa_modexpo(struct ica_rsa_modexpo *mex)
|
|||||||
continue;
|
continue;
|
||||||
/* get weight index of the card device */
|
/* get weight index of the card device */
|
||||||
weight = zc->speed_rating[func_code];
|
weight = zc->speed_rating[func_code];
|
||||||
if (pref_zc && atomic_read(&zc->load) + weight >=
|
if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
|
||||||
atomic_read(&pref_zc->load) + pref_weight)
|
|
||||||
continue;
|
continue;
|
||||||
for_each_zcrypt_queue(zq, zc) {
|
for_each_zcrypt_queue(zq, zc) {
|
||||||
/* check if device is online and eligible */
|
/* check if device is online and eligible */
|
||||||
if (!zq->online)
|
if (!zq->online)
|
||||||
continue;
|
continue;
|
||||||
if (pref_zq && atomic_read(&zq->load) + weight >=
|
if (zcrypt_queue_compare(zq, pref_zq,
|
||||||
atomic_read(&pref_zq->load) + pref_weight)
|
weight, pref_weight))
|
||||||
continue;
|
continue;
|
||||||
pref_zc = zc;
|
pref_zc = zc;
|
||||||
pref_zq = zq;
|
pref_zq = zq;
|
||||||
@ -289,15 +316,14 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
|
|||||||
continue;
|
continue;
|
||||||
/* get weight index of the card device */
|
/* get weight index of the card device */
|
||||||
weight = zc->speed_rating[func_code];
|
weight = zc->speed_rating[func_code];
|
||||||
if (pref_zc && atomic_read(&zc->load) + weight >=
|
if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
|
||||||
atomic_read(&pref_zc->load) + pref_weight)
|
|
||||||
continue;
|
continue;
|
||||||
for_each_zcrypt_queue(zq, zc) {
|
for_each_zcrypt_queue(zq, zc) {
|
||||||
/* check if device is online and eligible */
|
/* check if device is online and eligible */
|
||||||
if (!zq->online)
|
if (!zq->online)
|
||||||
continue;
|
continue;
|
||||||
if (pref_zq && atomic_read(&zq->load) + weight >=
|
if (zcrypt_queue_compare(zq, pref_zq,
|
||||||
atomic_read(&pref_zq->load) + pref_weight)
|
weight, pref_weight))
|
||||||
continue;
|
continue;
|
||||||
pref_zc = zc;
|
pref_zc = zc;
|
||||||
pref_zq = zq;
|
pref_zq = zq;
|
||||||
@ -346,8 +372,7 @@ static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
|
|||||||
continue;
|
continue;
|
||||||
/* get weight index of the card device */
|
/* get weight index of the card device */
|
||||||
weight = speed_idx_cca(func_code) * zc->speed_rating[SECKEY];
|
weight = speed_idx_cca(func_code) * zc->speed_rating[SECKEY];
|
||||||
if (pref_zc && atomic_read(&zc->load) + weight >=
|
if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
|
||||||
atomic_read(&pref_zc->load) + pref_weight)
|
|
||||||
continue;
|
continue;
|
||||||
for_each_zcrypt_queue(zq, zc) {
|
for_each_zcrypt_queue(zq, zc) {
|
||||||
/* check if device is online and eligible */
|
/* check if device is online and eligible */
|
||||||
@ -355,8 +380,8 @@ static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
|
|||||||
((*domain != (unsigned short) AUTOSELECT) &&
|
((*domain != (unsigned short) AUTOSELECT) &&
|
||||||
(*domain != AP_QID_QUEUE(zq->queue->qid))))
|
(*domain != AP_QID_QUEUE(zq->queue->qid))))
|
||||||
continue;
|
continue;
|
||||||
if (pref_zq && atomic_read(&zq->load) + weight >=
|
if (zcrypt_queue_compare(zq, pref_zq,
|
||||||
atomic_read(&pref_zq->load) + pref_weight)
|
weight, pref_weight))
|
||||||
continue;
|
continue;
|
||||||
pref_zc = zc;
|
pref_zc = zc;
|
||||||
pref_zq = zq;
|
pref_zq = zq;
|
||||||
@ -450,8 +475,7 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
|
|||||||
continue;
|
continue;
|
||||||
/* get weight index of the card device */
|
/* get weight index of the card device */
|
||||||
weight = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY];
|
weight = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY];
|
||||||
if (pref_zc && atomic_read(&zc->load) + weight >=
|
if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
|
||||||
atomic_read(&pref_zc->load) + pref_weight)
|
|
||||||
continue;
|
continue;
|
||||||
for_each_zcrypt_queue(zq, zc) {
|
for_each_zcrypt_queue(zq, zc) {
|
||||||
/* check if device is online and eligible */
|
/* check if device is online and eligible */
|
||||||
@ -460,8 +484,8 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
|
|||||||
!is_desired_ep11_queue(zq->queue->qid,
|
!is_desired_ep11_queue(zq->queue->qid,
|
||||||
target_num, targets)))
|
target_num, targets)))
|
||||||
continue;
|
continue;
|
||||||
if (pref_zq && atomic_read(&zq->load) + weight >=
|
if (zcrypt_queue_compare(zq, pref_zq,
|
||||||
atomic_read(&pref_zq->load) + pref_weight)
|
weight, pref_weight))
|
||||||
continue;
|
continue;
|
||||||
pref_zc = zc;
|
pref_zc = zc;
|
||||||
pref_zq = zq;
|
pref_zq = zq;
|
||||||
@ -510,15 +534,14 @@ static long zcrypt_rng(char *buffer)
|
|||||||
continue;
|
continue;
|
||||||
/* get weight index of the card device */
|
/* get weight index of the card device */
|
||||||
weight = zc->speed_rating[func_code];
|
weight = zc->speed_rating[func_code];
|
||||||
if (pref_zc && atomic_read(&zc->load) + weight >=
|
if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
|
||||||
atomic_read(&pref_zc->load) + pref_weight)
|
|
||||||
continue;
|
continue;
|
||||||
for_each_zcrypt_queue(zq, zc) {
|
for_each_zcrypt_queue(zq, zc) {
|
||||||
/* check if device is online and eligible */
|
/* check if device is online and eligible */
|
||||||
if (!zq->online)
|
if (!zq->online)
|
||||||
continue;
|
continue;
|
||||||
if (pref_zq && atomic_read(&zq->load) + weight >=
|
if (zcrypt_queue_compare(zq, pref_zq,
|
||||||
atomic_read(&pref_zq->load) + pref_weight)
|
weight, pref_weight))
|
||||||
continue;
|
continue;
|
||||||
pref_zc = zc;
|
pref_zc = zc;
|
||||||
pref_zq = zq;
|
pref_zq = zq;
|
||||||
|
Loading…
Reference in New Issue
Block a user