Commit 34a15167 authored by Ingo Tuchscherer's avatar Ingo Tuchscherer Committed by Martin Schwidefsky

s390/zcrypt: Introduce workload balancing

Crypto requests are very different in complexity and thus runtime.
Also various crypto adapters are differ with regard to the execution
time. Crypto requests can be balanced much better when the request
type and eligible crypto adapters are rated in a more precise
granularity. Therefore, request weights and adapter speed rates for
dedicated requests will be introduced.
Signed-off-by: default avatarIngo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 9af3e04e
This diff is collapsed.
......@@ -84,15 +84,32 @@ struct ica_z90_status {
*/
#define ZCRYPT_RNG_BUFFER_SIZE 4096
/*
* Identifier for Crypto Request Performance Index
*/
enum crypto_ops {
MEX_1K = 0,
MEX_2K,
MEX_4K,
CRT_1K,
CRT_2K,
CRT_4K,
HWRNG,
SECKEY,
NUM_OPS
};
struct zcrypt_device;
struct zcrypt_ops {
long (*rsa_modexpo)(struct zcrypt_device *, struct ica_rsa_modexpo *);
long (*rsa_modexpo_crt)(struct zcrypt_device *,
struct ica_rsa_modexpo_crt *);
long (*send_cprb)(struct zcrypt_device *, struct ica_xcRB *);
long (*send_ep11_cprb)(struct zcrypt_device *, struct ep11_urb *);
long (*rng)(struct zcrypt_device *, char *);
long (*send_cprb)(struct zcrypt_device *, struct ica_xcRB *,
struct ap_message *);
long (*send_ep11_cprb)(struct zcrypt_device *, struct ep11_urb *,
struct ap_message *);
long (*rng)(struct zcrypt_device *, char *, struct ap_message *);
struct list_head list; /* zcrypt ops list. */
struct module *owner;
int variant;
......@@ -112,7 +129,8 @@ struct zcrypt_device {
int min_mod_size; /* Min number of bits. */
int max_mod_size; /* Max number of bits. */
int short_crt; /* Card has crt length restriction. */
int speed_rating; /* Speed of the crypto device. */
int speed_rating[NUM_OPS]; /* Speed idx of crypto ops. */
int load; /* Utilization of the crypto device */
int request_count; /* # current requests. */
......
......@@ -43,9 +43,6 @@
#define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE
#define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */
#define CEX2A_SPEED_RATING 970
#define CEX3A_SPEED_RATING 900 /* Fixme: Needs finetuning */
#define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */
#define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
......@@ -87,6 +84,8 @@ static struct ap_driver zcrypt_cex2a_driver = {
static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
{
struct zcrypt_device *zdev = NULL;
int CEX2A_SPEED_IDX[] = { 800, 1000, 2000, 900, 1200, 2400, 0};
int CEX3A_SPEED_IDX[] = { 400, 500, 1000, 450, 550, 1200, 0};
int rc = 0;
switch (ap_dev->device_type) {
......@@ -99,7 +98,8 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
zdev->short_crt = 1;
zdev->speed_rating = CEX2A_SPEED_RATING;
memcpy(zdev->speed_rating, CEX2A_SPEED_IDX,
sizeof(CEX2A_SPEED_IDX));
zdev->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
break;
case AP_DEVICE_TYPE_CEX3A:
......@@ -117,7 +117,8 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
zdev->max_exp_bit_length = CEX3A_MAX_MOD_SIZE;
}
zdev->short_crt = 1;
zdev->speed_rating = CEX3A_SPEED_RATING;
memcpy(zdev->speed_rating, CEX3A_SPEED_IDX,
sizeof(CEX3A_SPEED_IDX));
break;
}
if (!zdev)
......@@ -125,6 +126,7 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
zdev->ops = zcrypt_msgtype(MSGTYPE50_NAME, MSGTYPE50_VARIANT_DEFAULT);
zdev->ap_dev = ap_dev;
zdev->online = 1;
zdev->load = zdev->speed_rating[0];
ap_device_init_reply(ap_dev, &zdev->reply);
ap_dev->private = zdev;
rc = zcrypt_device_register(zdev);
......
......@@ -24,13 +24,6 @@
#define CEX4C_MIN_MOD_SIZE 16 /* 256 bits */
#define CEX4C_MAX_MOD_SIZE 512 /* 4096 bits */
#define CEX4A_SPEED_RATING 900 /* TODO new card, new speed rating */
#define CEX4C_SPEED_RATING 6500 /* TODO new card, new speed rating */
#define CEX4P_SPEED_RATING 7000 /* TODO new card, new speed rating */
#define CEX5A_SPEED_RATING 450 /* TODO new card, new speed rating */
#define CEX5C_SPEED_RATING 3250 /* TODO new card, new speed rating */
#define CEX5P_SPEED_RATING 3500 /* TODO new card, new speed rating */
#define CEX4A_MAX_MESSAGE_SIZE MSGTYPE50_CRB3_MAX_MSG_SIZE
#define CEX4C_MAX_MESSAGE_SIZE MSGTYPE06_MAX_MSG_SIZE
......@@ -71,6 +64,16 @@ static struct ap_driver zcrypt_cex4_driver = {
static int zcrypt_cex4_probe(struct ap_device *ap_dev)
{
struct zcrypt_device *zdev = NULL;
/*
* Normalized speed ratings per crypto adapter
* MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
*/
int CEX4A_SPEED_IDX[] = { 5, 6, 59, 20, 115, 581, 0, 0};
int CEX5A_SPEED_IDX[] = { 3, 3, 6, 8, 32, 218, 0, 0};
int CEX4C_SPEED_IDX[] = { 24, 25, 82, 41, 138, 1111, 79, 8};
int CEX5C_SPEED_IDX[] = { 10, 14, 23, 17, 45, 242, 63, 4};
int CEX4P_SPEED_IDX[] = {142, 198, 1852, 203, 331, 1563, 0, 8};
int CEX5P_SPEED_IDX[] = { 49, 67, 131, 52, 85, 287, 0, 4};
int rc = 0;
switch (ap_dev->device_type) {
......@@ -82,10 +85,12 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev)
return -ENOMEM;
if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) {
zdev->type_string = "CEX4A";
zdev->speed_rating = CEX4A_SPEED_RATING;
memcpy(zdev->speed_rating, CEX4A_SPEED_IDX,
sizeof(CEX4A_SPEED_IDX));
} else {
zdev->type_string = "CEX5A";
zdev->speed_rating = CEX5A_SPEED_RATING;
memcpy(zdev->speed_rating, CEX5A_SPEED_IDX,
sizeof(CEX5A_SPEED_IDX));
}
zdev->user_space_type = ZCRYPT_CEX3A;
zdev->min_mod_size = CEX4A_MIN_MOD_SIZE;
......@@ -110,10 +115,12 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev)
return -ENOMEM;
if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) {
zdev->type_string = "CEX4C";
zdev->speed_rating = CEX4C_SPEED_RATING;
memcpy(zdev->speed_rating, CEX4C_SPEED_IDX,
sizeof(CEX4C_SPEED_IDX));
} else {
zdev->type_string = "CEX5C";
zdev->speed_rating = CEX5C_SPEED_RATING;
memcpy(zdev->speed_rating, CEX5C_SPEED_IDX,
sizeof(CEX5C_SPEED_IDX));
}
zdev->user_space_type = ZCRYPT_CEX3C;
zdev->min_mod_size = CEX4C_MIN_MOD_SIZE;
......@@ -128,10 +135,12 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev)
return -ENOMEM;
if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) {
zdev->type_string = "CEX4P";
zdev->speed_rating = CEX4P_SPEED_RATING;
memcpy(zdev->speed_rating, CEX4P_SPEED_IDX,
sizeof(CEX4P_SPEED_IDX));
} else {
zdev->type_string = "CEX5P";
zdev->speed_rating = CEX5P_SPEED_RATING;
memcpy(zdev->speed_rating, CEX5P_SPEED_IDX,
sizeof(CEX5P_SPEED_IDX));
}
zdev->user_space_type = ZCRYPT_CEX4;
zdev->min_mod_size = CEX4C_MIN_MOD_SIZE;
......@@ -147,6 +156,7 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev)
return -ENODEV;
zdev->ap_dev = ap_dev;
zdev->online = 1;
zdev->load = zdev->speed_rating[0];
ap_device_init_reply(ap_dev, &zdev->reply);
ap_dev->private = zdev;
rc = zcrypt_device_register(zdev);
......
......@@ -173,6 +173,38 @@ struct type80_hdr {
unsigned char reserved3[8];
} __packed;
unsigned int get_rsa_modex_fc(struct ica_rsa_modexpo *mex, int *fcode)
{
if (!mex->inputdatalength)
return -EINVAL;
if (mex->inputdatalength <= 128) /* 1024 bit */
*fcode = MEX_1K;
else if (mex->inputdatalength <= 256) /* 2048 bit */
*fcode = MEX_2K;
else /* 4096 bit */
*fcode = MEX_4K;
return 0;
}
unsigned int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *crt, int *fcode)
{
if (!crt->inputdatalength)
return -EINVAL;
if (crt->inputdatalength <= 128) /* 1024 bit */
*fcode = CRT_1K;
else if (crt->inputdatalength <= 256) /* 2048 bit */
*fcode = CRT_2K;
else /* 4096 bit */
*fcode = CRT_4K;
return 0;
}
/**
* Convert a ICAMEX message to a type50 MEX message.
*
......
......@@ -35,6 +35,9 @@
#define MSGTYPE_ADJUSTMENT 0x08 /*type04 extension (not needed in type50)*/
unsigned int get_rsa_modex_fc(struct ica_rsa_modexpo *, int *);
unsigned int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *, int *);
void zcrypt_msgtype50_init(void);
void zcrypt_msgtype50_exit(void);
......
This diff is collapsed.
......@@ -116,15 +116,25 @@ struct type86_fmt2_ext {
unsigned int offset4; /* 0x00000000 */
} __packed;
unsigned int get_cprb_fc(struct ica_xcRB *, struct ap_message *, int *);
unsigned int get_ep11cprb_fc(struct ep11_urb *, struct ap_message *, int *);
unsigned int get_rng_fc(struct ap_message *, int *);
#define LOW 10
#define MEDIUM 100
#define HIGH 500
int speed_idx_cca(int);
int speed_idx_ep11(int);
/**
* Prepare a type6 CPRB message for random number generation
*
* @ap_dev: AP device pointer
* @ap_msg: pointer to AP message
*/
static inline void rng_type6CPRB_msgX(struct ap_device *ap_dev,
struct ap_message *ap_msg,
unsigned random_number_length)
static inline void rng_type6CPRB_msgX(struct ap_message *ap_msg,
unsigned int random_number_length)
{
struct {
struct type6_hdr hdr;
......@@ -156,7 +166,6 @@ static inline void rng_type6CPRB_msgX(struct ap_device *ap_dev,
msg->hdr.FromCardLen2 = random_number_length,
msg->cprbx = local_cprbx;
msg->cprbx.rpl_datal = random_number_length,
msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
memcpy(msg->function_code, msg->hdr.function_code, 0x02);
msg->rule_length = 0x0a;
memcpy(msg->rule, "RANDOM ", 8);
......
......@@ -46,11 +46,6 @@
#define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
#define CEX3C_MAX_MOD_SIZE 512 /* 4096 bits */
#define PCIXCC_MCL2_SPEED_RATING 7870
#define PCIXCC_MCL3_SPEED_RATING 7870
#define CEX2C_SPEED_RATING 7000
#define CEX3C_SPEED_RATING 6500
#define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
......@@ -220,6 +215,15 @@ static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
struct type86_fmt2_ext fmt2;
struct CPRBX cprbx;
} __attribute__((packed)) *reply;
struct {
struct type6_hdr hdr;
struct CPRBX cprbx;
char function_code[2];
short int rule_length;
char rule[8];
short int verb_length;
short int key_length;
} __packed * msg;
int rc, i;
ap_init_message(&ap_msg);
......@@ -227,7 +231,11 @@ static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
if (!ap_msg.message)
return -ENOMEM;
rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
rng_type6CPRB_msgX(&ap_msg, 4);
msg = ap_msg.message;
msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
ap_msg.length);
if (rc)
......@@ -267,6 +275,14 @@ static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
{
struct zcrypt_device *zdev;
/*
* Normalized speed ratings per crypto adapter
* MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
*/
int PCIXCC_MCL2_SPEED_IDX[] = {10, 10, 10, 10, 10, 10, 10, 10};
int PCIXCC_MCL3_SPEED_IDX[] = { 8, 8, 8, 8, 8, 8, 8, 8};
int CEX2C_SPEED_IDX[] = {1000, 1400, 2400, 1100, 1500, 2600, 100, 12};
int CEX3C_SPEED_IDX[] = { 500, 700, 1400, 550, 800, 1500, 80, 10};
int rc = 0;
zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE);
......@@ -284,13 +300,15 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->user_space_type = rc;
if (rc == ZCRYPT_PCIXCC_MCL2) {
zdev->type_string = "PCIXCC_MCL2";
zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
memcpy(zdev->speed_rating, PCIXCC_MCL2_SPEED_IDX,
sizeof(PCIXCC_MCL2_SPEED_IDX));
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
} else {
zdev->type_string = "PCIXCC_MCL3";
zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
memcpy(zdev->speed_rating, PCIXCC_MCL3_SPEED_IDX,
sizeof(PCIXCC_MCL3_SPEED_IDX));
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
......@@ -299,7 +317,8 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
case AP_DEVICE_TYPE_CEX2C:
zdev->user_space_type = ZCRYPT_CEX2C;
zdev->type_string = "CEX2C";
zdev->speed_rating = CEX2C_SPEED_RATING;
memcpy(zdev->speed_rating, CEX2C_SPEED_IDX,
sizeof(CEX2C_SPEED_IDX));
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
......@@ -307,7 +326,8 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
case AP_DEVICE_TYPE_CEX3C:
zdev->user_space_type = ZCRYPT_CEX3C;
zdev->type_string = "CEX3C";
zdev->speed_rating = CEX3C_SPEED_RATING;
memcpy(zdev->speed_rating, CEX3C_SPEED_IDX,
sizeof(CEX3C_SPEED_IDX));
zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
......@@ -315,6 +335,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
default:
goto out_free;
}
zdev->load = zdev->speed_rating[0];
rc = zcrypt_pcixcc_rng_supported(ap_dev);
if (rc < 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment