From owner-svn-src-all@FreeBSD.ORG Thu Dec 18 08:32:08 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 145CE910; Thu, 18 Dec 2014 08:32:08 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F34B118D0; Thu, 18 Dec 2014 08:32:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sBI8W7W3024784; Thu, 18 Dec 2014 08:32:07 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sBI8W7dh024780; Thu, 18 Dec 2014 08:32:07 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201412180832.sBI8W7dh024780@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Thu, 18 Dec 2014 08:32:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r275888 - stable/10/sys/cam/ctl X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Dec 2014 08:32:08 -0000 Author: mav Date: Thu Dec 18 08:32:06 2014 New Revision: 275888 URL: https://svnweb.freebsd.org/changeset/base/275888 Log: MFC r275458: Do not pre-allocate UNIT ATTENTIONs storage for every possible initiator. Abusing ability of major UAs cover minor ones we may not account UAs for inactive ports. Allocate UAs storage for port and start accounting only after some initiator from that port fetched its first POWER ON OCCURRED. This reduces per-LUN CTL memory usage from >1MB to less then 100K. Modified: stable/10/sys/cam/ctl/ctl.c stable/10/sys/cam/ctl/ctl_error.c stable/10/sys/cam/ctl/ctl_error.h stable/10/sys/cam/ctl/ctl_private.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ctl/ctl.c ============================================================================== --- stable/10/sys/cam/ctl/ctl.c Thu Dec 18 08:31:13 2014 (r275887) +++ stable/10/sys/cam/ctl/ctl.c Thu Dec 18 08:32:06 2014 (r275888) @@ -964,12 +964,70 @@ ctl_copy_sense_data(union ctl_ha_msg *sr dest->io_hdr.status = src->hdr.status; } +static void +ctl_est_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua) +{ + ctl_ua_type *pu; + + mtx_assert(&lun->lun_lock, MA_OWNED); + pu = lun->pending_ua[initidx / CTL_MAX_INIT_PER_PORT]; + if (pu == NULL) + return; + pu[initidx % CTL_MAX_INIT_PER_PORT] |= ua; +} + +static void +ctl_est_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua) +{ + int i, j; + + mtx_assert(&lun->lun_lock, MA_OWNED); + for (i = 0; i < CTL_MAX_PORTS; i++) { + if (lun->pending_ua[i] == NULL) + continue; + for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) { + if (i * CTL_MAX_INIT_PER_PORT + j == except) + continue; + lun->pending_ua[i][j] |= ua; + } + } +} + +static void +ctl_clr_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua) +{ + ctl_ua_type *pu; + + mtx_assert(&lun->lun_lock, MA_OWNED); + pu = lun->pending_ua[initidx / CTL_MAX_INIT_PER_PORT]; + if (pu == NULL) + return; + pu[initidx % CTL_MAX_INIT_PER_PORT] &= ~ua; +} + +static void +ctl_clr_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua) +{ + int i, j; + + mtx_assert(&lun->lun_lock, MA_OWNED); + for (i = 0; i < CTL_MAX_PORTS; i++) { + if (lun->pending_ua[i] == NULL) + continue; + for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) { + if (i * CTL_MAX_INIT_PER_PORT + j == except) + continue; + lun->pending_ua[i][j] &= ~ua; + } + } +} + static int ctl_ha_state_sysctl(SYSCTL_HANDLER_ARGS) { struct ctl_softc *softc = (struct ctl_softc *)arg1; struct ctl_lun *lun; - int error, value, i; + int error, value; if (softc->flags & CTL_FLAG_ACTIVE_SHELF) value = 0; @@ -987,8 +1045,7 @@ ctl_ha_state_sysctl(SYSCTL_HANDLER_ARGS) softc->flags &= ~CTL_FLAG_ACTIVE_SHELF; STAILQ_FOREACH(lun, &softc->lun_list, links) { mtx_lock(&lun->lun_lock); - for (i = 0; i < CTL_MAX_INITIATORS; i++) - lun->pending_ua[i] |= CTL_UA_ASYM_ACC_CHANGE; + ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE); mtx_unlock(&lun->lun_lock); } mtx_unlock(&softc->ctl_lock); @@ -4549,19 +4606,13 @@ ctl_alloc_lun(struct ctl_softc *ctl_soft ctl_init_log_page_index(lun); /* - * Set the poweron UA for all initiators on this LUN only. - */ - for (i = 0; i < CTL_MAX_INITIATORS; i++) - lun->pending_ua[i] = CTL_UA_POWERON; - - /* * Now, before we insert this lun on the lun list, set the lun * inventory changed UA for all other luns. */ STAILQ_FOREACH(nlun, &ctl_softc->lun_list, links) { - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - nlun->pending_ua[i] |= CTL_UA_LUN_CHANGE; - } + mtx_lock(&nlun->lun_lock); + ctl_est_ua_all(nlun, -1, CTL_UA_LUN_CHANGE); + mtx_unlock(&nlun->lun_lock); } STAILQ_INSERT_TAIL(&ctl_softc->lun_list, lun, links); @@ -4696,18 +4747,18 @@ ctl_free_lun(struct ctl_lun *lun) ctl_tpc_lun_shutdown(lun); mtx_destroy(&lun->lun_lock); free(lun->lun_devid, M_CTL); - for (i = 0; i < 2 * CTL_MAX_PORTS; i++) { - if (lun->pr_keys[i] != NULL) - free(lun->pr_keys[i], M_CTL); - } + for (i = 0; i < CTL_MAX_PORTS; i++) + free(lun->pending_ua[i], M_CTL); + for (i = 0; i < 2 * CTL_MAX_PORTS; i++) + free(lun->pr_keys[i], M_CTL); free(lun->write_buffer, M_CTL); if (lun->flags & CTL_LUN_MALLOCED) free(lun, M_CTL); STAILQ_FOREACH(nlun, &softc->lun_list, links) { - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - nlun->pending_ua[i] |= CTL_UA_LUN_CHANGE; - } + mtx_lock(&nlun->lun_lock); + ctl_est_ua_all(nlun, -1, CTL_UA_LUN_CHANGE); + mtx_unlock(&nlun->lun_lock); } return (0); @@ -4985,19 +5036,10 @@ ctl_lun_operable(struct ctl_be_lun *be_l void ctl_lun_capacity_changed(struct ctl_be_lun *be_lun) { - struct ctl_lun *lun; - struct ctl_softc *softc; - int i; - - softc = control_softc; - - lun = (struct ctl_lun *)be_lun->ctl_lun; + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); - - for (i = 0; i < CTL_MAX_INITIATORS; i++) - lun->pending_ua[i] |= CTL_UA_CAPACITY_CHANGED; - + ctl_est_ua_all(lun, -1, CTL_UA_CAPACITY_CHANGED); mtx_unlock(&lun->lun_lock); } @@ -6045,19 +6087,8 @@ ctl_control_page_handler(struct ctl_scsi saved_cp->eca_and_aen |= user_cp->eca_and_aen & SCP_SWP; set_ua = 1; } - if (set_ua != 0) { - int i; - /* - * Let other initiators know that the mode - * parameters for this LUN have changed. - */ - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - if (i == initidx) - continue; - - lun->pending_ua[i] |= CTL_UA_MODE_CHANGE; - } - } + if (set_ua != 0) + ctl_est_ua_all(lun, initidx, CTL_UA_MODE_CHANGE); mtx_unlock(&lun->lun_lock); return (0); @@ -6093,19 +6124,8 @@ ctl_caching_sp_handler(struct ctl_scsiio saved_cp->flags1 |= user_cp->flags1 & (SCP_WCE | SCP_RCD); set_ua = 1; } - if (set_ua != 0) { - int i; - /* - * Let other initiators know that the mode - * parameters for this LUN have changed. - */ - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - if (i == initidx) - continue; - - lun->pending_ua[i] |= CTL_UA_MODE_CHANGE; - } - } + if (set_ua != 0) + ctl_est_ua_all(lun, initidx, CTL_UA_MODE_CHANGE); mtx_unlock(&lun->lun_lock); return (0); @@ -7893,7 +7913,7 @@ ctl_set_res_ua(struct ctl_lun *lun, uint int off = lun->ctl_softc->persis_offset; if (residx >= off && residx < off + CTL_MAX_INITIATORS) - lun->pending_ua[residx - off] |= ua; + ctl_est_ua(lun, residx - off, ua); } /* @@ -8435,8 +8455,8 @@ ctl_persistent_reserve_out(struct ctl_sc if (ctl_get_prkey(lun, i + softc->persis_offset) == 0) continue; - lun->pending_ua[i] |= - CTL_UA_RES_RELEASE; + ctl_est_ua(lun, i, + CTL_UA_RES_RELEASE); } } lun->res_type = 0; @@ -8584,7 +8604,7 @@ ctl_persistent_reserve_out(struct ctl_sc ctl_get_prkey(lun, i + softc->persis_offset) == 0) continue; - lun->pending_ua[i] |= CTL_UA_RES_RELEASE; + ctl_est_ua(lun, i, CTL_UA_RES_RELEASE); } } mtx_unlock(&lun->lun_lock); @@ -8703,8 +8723,7 @@ ctl_hndl_per_res_out_on_other_sc(union c softc->persis_offset) == 0) continue; - lun->pending_ua[i] |= - CTL_UA_RES_RELEASE; + ctl_est_ua(lun, i, CTL_UA_RES_RELEASE); } } lun->res_type = 0; @@ -8734,8 +8753,7 @@ ctl_hndl_per_res_out_on_other_sc(union c && lun->res_type != SPR_TYPE_WR_EX) { for (i = 0; i < CTL_MAX_INITIATORS; i++) if (ctl_get_prkey(lun, i + softc->persis_offset) != 0) - lun->pending_ua[i] |= - CTL_UA_RES_RELEASE; + ctl_est_ua(lun, i, CTL_UA_RES_RELEASE); } lun->flags &= ~CTL_LUN_PR_RESERVED; @@ -9308,7 +9326,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio */ if (request_lun != NULL) { mtx_lock(&lun->lun_lock); - lun->pending_ua[initidx] &= ~CTL_UA_LUN_CHANGE; + ctl_clr_ua(lun, initidx, CTL_UA_RES_RELEASE); mtx_unlock(&lun->lun_lock); } } @@ -9363,6 +9381,7 @@ ctl_request_sense(struct ctl_scsiio *cts uint32_t initidx; int have_error; scsi_sense_data_type sense_format; + ctl_ua_type ua_type; cdb = (struct scsi_request_sense *)ctsio->cdb; @@ -9447,11 +9466,8 @@ ctl_request_sense(struct ctl_scsiio *cts have_error = 1; } else #endif - if (lun->pending_ua[initidx] != CTL_UA_NONE) { - ctl_ua_type ua_type; - - ua_type = ctl_build_ua(&lun->pending_ua[initidx], - sense_ptr, sense_format); + { + ua_type = ctl_build_ua(lun, initidx, sense_ptr, sense_format); if (ua_type != CTL_UA_NONE) have_error = 1; } @@ -11122,7 +11138,6 @@ ctl_failover(void) union ctl_io *next_io, *pending_io; union ctl_io *io; int lun_idx; - int i; ctl_softc = control_softc; @@ -11257,13 +11272,7 @@ ctl_failover(void) } } - /* - * Build Unit Attention - */ - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - lun->pending_ua[i] |= - CTL_UA_ASYM_ACC_CHANGE; - } + ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE); } else if (((lun->flags & CTL_LUN_PRIMARY_SC) == 0) && (ctl_softc->ha_mode == CTL_HA_MODE_SER_ONLY)) { printf("FAILOVER: secondary lun %d\n", lun_idx); @@ -11352,13 +11361,7 @@ ctl_failover(void) } } - /* - * Build Unit Attention - */ - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - lun->pending_ua[i] |= - CTL_UA_ASYM_ACC_CHANGE; - } + ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE); } else { panic("Unhandled HA mode failover, LUN flags = %#x, " "ha_mode = #%x", lun->flags, ctl_softc->ha_mode); @@ -11494,28 +11497,22 @@ ctl_scsiio_precheck(struct ctl_softc *ct */ if ((entry->flags & CTL_CMD_FLAG_NO_SENSE) == 0) { ctl_ua_type ua_type; + scsi_sense_data_type sense_format; - if (lun->pending_ua[initidx] != CTL_UA_NONE) { - scsi_sense_data_type sense_format; - - if (lun != NULL) - sense_format = (lun->flags & - CTL_LUN_SENSE_DESC) ? SSD_TYPE_DESC : - SSD_TYPE_FIXED; - else - sense_format = SSD_TYPE_FIXED; + if (lun->flags & CTL_LUN_SENSE_DESC) + sense_format = SSD_TYPE_DESC; + else + sense_format = SSD_TYPE_FIXED; - ua_type = ctl_build_ua(&lun->pending_ua[initidx], - &ctsio->sense_data, sense_format); - if (ua_type != CTL_UA_NONE) { - ctsio->scsi_status = SCSI_STATUS_CHECK_COND; - ctsio->io_hdr.status = CTL_SCSI_ERROR | - CTL_AUTOSENSE; - ctsio->sense_len = SSD_FULL_SIZE; - mtx_unlock(&lun->lun_lock); - ctl_done((union ctl_io *)ctsio); - return (retval); - } + ua_type = ctl_build_ua(lun, initidx, &ctsio->sense_data, + sense_format); + if (ua_type != CTL_UA_NONE) { + mtx_unlock(&lun->lun_lock); + ctsio->scsi_status = SCSI_STATUS_CHECK_COND; + ctsio->io_hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE; + ctsio->sense_len = SSD_FULL_SIZE; + ctl_done((union ctl_io *)ctsio); + return (retval); } } @@ -11794,7 +11791,9 @@ ctl_lun_reset(struct ctl_lun *lun, union #if 0 uint32_t initidx; #endif +#ifdef CTL_WITH_CA int i; +#endif mtx_lock(&lun->lun_lock); /* @@ -11813,11 +11812,9 @@ ctl_lun_reset(struct ctl_lun *lun, union */ #if 0 initidx = ctl_get_initindex(&io->io_hdr.nexus); - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - if (initidx == i) - continue; - lun->pending_ua[i] |= ua_type; - } + ctl_est_ua_all(lun, initidx, ua_type); +#else + ctl_est_ua_all(lun, -1, ua_type); #endif /* @@ -11830,12 +11827,10 @@ ctl_lun_reset(struct ctl_lun *lun, union */ lun->flags &= ~CTL_LUN_RESERVED; - for (i = 0; i < CTL_MAX_INITIATORS; i++) { #ifdef CTL_WITH_CA + for (i = 0; i < CTL_MAX_INITIATORS; i++) ctl_clear_mask(lun->have_ca, i); #endif - lun->pending_ua[i] |= ua_type; - } mtx_unlock(&lun->lun_lock); return (0); @@ -11937,7 +11932,7 @@ ctl_i_t_nexus_reset(union ctl_io *io) #endif if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == residx)) lun->flags &= ~CTL_LUN_RESERVED; - lun->pending_ua[initidx] |= CTL_UA_I_T_NEXUS_LOSS; + ctl_est_ua(lun, initidx, CTL_UA_I_T_NEXUS_LOSS); mtx_unlock(&lun->lun_lock); } mtx_unlock(&softc->ctl_lock); @@ -13953,14 +13948,11 @@ ctl_thresh_thread(void *arg) if (lun->lasttpt == 0 || time_uptime - lun->lasttpt >= CTL_LBP_UA_PERIOD) { lun->lasttpt = time_uptime; - for (i = 0; i < CTL_MAX_INITIATORS; i++) - lun->pending_ua[i] |= - CTL_UA_THIN_PROV_THRES; + ctl_est_ua_all(lun, -1, CTL_UA_THIN_PROV_THRES); } } else { lun->lasttpt = 0; - for (i = 0; i < CTL_MAX_INITIATORS; i++) - lun->pending_ua[i] &= ~CTL_UA_THIN_PROV_THRES; + ctl_clr_ua_all(lun, -1, CTL_UA_THIN_PROV_THRES); } mtx_unlock(&lun->lun_lock); } Modified: stable/10/sys/cam/ctl/ctl_error.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_error.c Thu Dec 18 08:31:13 2014 (r275887) +++ stable/10/sys/cam/ctl/ctl_error.c Thu Dec 18 08:32:06 2014 (r275888) @@ -367,16 +367,35 @@ ctl_set_ua(struct ctl_scsiio *ctsio, int } ctl_ua_type -ctl_build_ua(ctl_ua_type *ua_type, struct scsi_sense_data *sense, - scsi_sense_data_type sense_format) +ctl_build_ua(struct ctl_lun *lun, uint32_t initidx, + struct scsi_sense_data *sense, scsi_sense_data_type sense_format) { + ctl_ua_type *ua; ctl_ua_type ua_to_build, ua_to_clear; int asc, ascq; + uint32_t p, i; - if (*ua_type == CTL_UA_NONE) + mtx_assert(&lun->lun_lock, MA_OWNED); + p = initidx / CTL_MAX_INIT_PER_PORT; + if ((ua = lun->pending_ua[p]) == NULL) { + mtx_unlock(&lun->lun_lock); + ua = malloc(sizeof(ctl_ua_type) * CTL_MAX_INIT_PER_PORT, + M_CTL, M_WAITOK); + mtx_lock(&lun->lun_lock); + if (lun->pending_ua[p] == NULL) { + lun->pending_ua[p] = ua; + for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) + ua[i] = CTL_UA_POWERON; + } else { + free(ua, M_CTL); + ua = lun->pending_ua[p]; + } + } + i = initidx % CTL_MAX_INIT_PER_PORT; + if (ua[i] == CTL_UA_NONE) return (CTL_UA_NONE); - ua_to_build = (1 << (ffs(*ua_type) - 1)); + ua_to_build = (1 << (ffs(ua[i]) - 1)); ua_to_clear = ua_to_build; switch (ua_to_build) { @@ -482,7 +501,7 @@ ctl_build_ua(ctl_ua_type *ua_type, struc SSD_ELEM_NONE); /* We're reporting this UA, so clear it */ - *ua_type &= ~ua_to_clear; + ua[i] &= ~ua_to_clear; return (ua_to_build); } Modified: stable/10/sys/cam/ctl/ctl_error.h ============================================================================== --- stable/10/sys/cam/ctl/ctl_error.h Thu Dec 18 08:31:13 2014 (r275887) +++ stable/10/sys/cam/ctl/ctl_error.h Thu Dec 18 08:32:06 2014 (r275888) @@ -42,6 +42,8 @@ #ifndef _CTL_ERROR_H_ #define _CTL_ERROR_H_ +struct ctl_lun; + void ctl_set_sense_data_va(struct scsi_sense_data *sense_data, void *lun, scsi_sense_data_type sense_format, int current_error, int sense_key, int asc, int ascq, va_list ap); @@ -55,8 +57,8 @@ void ctl_sense_to_desc(struct scsi_sense void ctl_sense_to_fixed(struct scsi_sense_data_desc *sense_src, struct scsi_sense_data_fixed *sense_dest); void ctl_set_ua(struct ctl_scsiio *ctsio, int asc, int ascq); -ctl_ua_type ctl_build_ua(ctl_ua_type *ua_type, struct scsi_sense_data *sense, - scsi_sense_data_type sense_format); +ctl_ua_type ctl_build_ua(struct ctl_lun *lun, uint32_t initidx, + struct scsi_sense_data *sense, scsi_sense_data_type sense_format); void ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio); void ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag); void ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command, Modified: stable/10/sys/cam/ctl/ctl_private.h ============================================================================== --- stable/10/sys/cam/ctl/ctl_private.h Thu Dec 18 08:31:13 2014 (r275887) +++ stable/10/sys/cam/ctl/ctl_private.h Thu Dec 18 08:32:06 2014 (r275888) @@ -403,7 +403,7 @@ struct ctl_lun { uint32_t have_ca[CTL_MAX_INITIATORS >> 5]; struct scsi_sense_data pending_sense[CTL_MAX_INITIATORS]; #endif - ctl_ua_type pending_ua[CTL_MAX_INITIATORS]; + ctl_ua_type *pending_ua[CTL_MAX_PORTS]; time_t lasttpt; struct ctl_mode_pages mode_pages; struct ctl_log_pages log_pages;