Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e47de21d authored by Ingo Tuchscherer's avatar Ingo Tuchscherer Committed by Martin Schwidefsky
Browse files

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: default avatarIngo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent b886a9d1
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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)
+1 −3
Original line number Original line Diff line number Diff line
@@ -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);
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -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);
+43 −20
Original line number Original line Diff line number Diff line
@@ -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;