Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sbp-target: Conversion to percpu_ida tag pre-allocation

This patch converts sbp-target to use struct sbp_target_request
descriptor tag pre-allocation using percpu_ida.

(Fix sbp_mgt_get_req() IS_ERR failure checking - Dan Carpenter)
(Add missing sbp_target_request tag memset - Chris Boot)

Acked-by: Chris Boot <bootc@bootc.net>
Tested-by: Chris Boot <bootc@bootc.net>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

+30 -6
+30 -6
drivers/target/sbp/sbp_target.c
··· 209 209 INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work); 210 210 sess->guid = guid; 211 211 212 - sess->se_sess = target_alloc_session(&tpg->se_tpg, 0, 0, TARGET_PROT_NORMAL, 213 - guid_str, sess, NULL); 212 + sess->se_sess = target_alloc_session(&tpg->se_tpg, 128, 213 + sizeof(struct sbp_target_request), 214 + TARGET_PROT_NORMAL, guid_str, 215 + sess, NULL); 214 216 if (IS_ERR(sess->se_sess)) { 215 217 pr_err("failed to init se_session\n"); 216 218 ret = PTR_ERR(sess->se_sess); ··· 923 921 return active; 924 922 } 925 923 924 + static struct sbp_target_request *sbp_mgt_get_req(struct sbp_session *sess, 925 + struct fw_card *card, u64 next_orb) 926 + { 927 + struct se_session *se_sess = sess->se_sess; 928 + struct sbp_target_request *req; 929 + int tag; 930 + 931 + tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_ATOMIC); 932 + if (tag < 0) 933 + return ERR_PTR(-ENOMEM); 934 + 935 + req = &((struct sbp_target_request *)se_sess->sess_cmd_map)[tag]; 936 + memset(req, 0, sizeof(*req)); 937 + req->se_cmd.map_tag = tag; 938 + req->se_cmd.tag = next_orb; 939 + 940 + return req; 941 + } 942 + 926 943 static void tgt_agent_fetch_work(struct work_struct *work) 927 944 { 928 945 struct sbp_target_agent *agent = ··· 953 932 u64 next_orb = agent->orb_pointer; 954 933 955 934 while (next_orb && tgt_agent_check_active(agent)) { 956 - req = kzalloc(sizeof(*req), GFP_KERNEL); 957 - if (!req) { 935 + req = sbp_mgt_get_req(sess, sess->card, next_orb); 936 + if (IS_ERR(req)) { 958 937 spin_lock_bh(&agent->lock); 959 938 agent->state = AGENT_STATE_DEAD; 960 939 spin_unlock_bh(&agent->lock); ··· 1451 1430 1452 1431 static void sbp_free_request(struct sbp_target_request *req) 1453 1432 { 1433 + struct se_cmd *se_cmd = &req->se_cmd; 1434 + struct se_session *se_sess = se_cmd->se_sess; 1435 + 1454 1436 kfree(req->pg_tbl); 1455 1437 kfree(req->cmd_buf); 1456 - kfree(req); 1438 + 1439 + percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag); 1457 1440 } 1458 1441 1459 1442 static void sbp_mgt_agent_process(struct work_struct *work) ··· 1617 1592 rcode = RCODE_CONFLICT_ERROR; 1618 1593 goto out; 1619 1594 } 1620 - 1621 1595 req = kzalloc(sizeof(*req), GFP_ATOMIC); 1622 1596 if (!req) { 1623 1597 rcode = RCODE_CONFLICT_ERROR;