From patchwork Mon Aug 19 16:08:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Merla, ShivaKrishna" X-Patchwork-Id: 2846853 X-Patchwork-Delegate: snitzer@redhat.com Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 33D519F2F4 for ; Tue, 20 Aug 2013 06:21:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 180F820292 for ; Tue, 20 Aug 2013 06:21:54 +0000 (UTC) Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by mail.kernel.org (Postfix) with ESMTP id D437E201E0 for ; Tue, 20 Aug 2013 06:21:51 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r7K6Gg09001848; Tue, 20 Aug 2013 02:16:43 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r7JG96NG004725 for ; Mon, 19 Aug 2013 12:09:06 -0400 Received: from mx1.redhat.com (ext-mx12.extmail.prod.ext.phx2.redhat.com [10.5.110.17]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r7JG95Ro027251; Mon, 19 Aug 2013 12:09:05 -0400 Received: from mx12.netapp.com (mx12.netapp.com [216.240.18.77]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r7JG90uC006921; Mon, 19 Aug 2013 12:09:01 -0400 X-IronPort-AV: E=Sophos;i="4.89,914,1367996400"; d="scan'208";a="82181930" Received: from vmwexceht06-prd.hq.netapp.com ([10.106.77.104]) by mx12-out.netapp.com with ESMTP; 19 Aug 2013 09:08:59 -0700 Received: from SACEXCMBX02-PRD.hq.netapp.com ([169.254.1.122]) by vmwexceht06-prd.hq.netapp.com ([10.106.77.104]) with mapi id 14.03.0123.003; Mon, 19 Aug 2013 09:08:59 -0700 From: "Merla, ShivaKrishna" To: device-mapper development , "linux-scsi@vger.kernel.org" Thread-Topic: [dm-devel] [PATCH][RESEND] scsi_dh_rdac:Log batched lun information with mode select command Thread-Index: Ac6c9ZVSVArDud1eSKOZIBRSvEDm+A== Date: Mon, 19 Aug 2013 16:08:58 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.104.60.114] MIME-Version: 1.0 X-RedHat-Spam-Score: -10.1 (BAYES_00, DCC_REPUT_00_12, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS, URIBL_BLOCKED) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-Scanned-By: MIMEDefang 2.68 on 10.5.110.17 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id r7JG96NG004725 X-loop: dm-devel@redhat.com X-Mailman-Approved-At: Tue, 20 Aug 2013 02:16:41 -0400 Cc: James Bottomley , "snitzer@redhat.com" Subject: [dm-devel] [PATCH][RESEND] scsi_dh_rdac:Log batched lun information with mode select command X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Resending again. Please provide your inputs on this. This change is important for NetApp to assist in triaging issues. With RDAC mode, mode select is batched together for multiple LUNs and sent to one of the path for failover. Currently Modeselect is logged without details of LUNs batched together. Modeselect command can be logged with batched lun id information so that failover command can be tracked on per LUN basis in the syslog. Incase if the luns involved in mode select are 16 or less, plain lun number information is logged. If luns are large, all the lun numbers are encoded into 256 bit format and logged as hex string. Encode Logic for each lun number into 32 byte string: lun_bit_string[lun/8] |= (1 << (lun % 8)); Decode Logic for any specific lun number which is set in mode select in 32 byte string: lun number = number of bits before the specific byte + position index [0-7] of the set bit in the specific byte from R->L. Log Snippet: Jul 24 17:46:05 Linux-215 kernel: sd 30:0:0:94: rdac: array Marryjane, ctlr 1, queueing MODE_SELECT command for 11 lun(s) [43,89,93,94,95,97,99,100,106,107,111] Jul 24 17:46:06 Linux-215 kernel: sd 30:0:0:94: rdac: array Marryjane, ctlr 1, MODE_SELECT completed for 11 lun(s) [43,89,93,94,95,97,99,100,106,107,111] Jul 24 17:49:17 Linux-215 kernel: sd 29:0:1:9: rdac: array Marryjane, ctlr 0, queueing MODE_SELECT command for 54 lun(s) [0082a0aa8aaaeaaaaafaeaeb5aad000000000000000000000000000000000000] Jul 24 17:49:19 Linux-215 kernel: sd 29:0:1:9: rdac: array Marryjane, ctlr 0, MODE_SELECT completed for 54 lun(s) [0082a0aa8aaaeaaaaafaeaeb5aad000000000000000000000000000000000000] Signed-off-by: Shiva Krishna Merla Signed-off-by: Krishnasamy Somasundaram Signed-off-by: Sean Stewart --- -- -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel --- a/drivers/scsi/device_handler/scsi_dh_rdac.c.orig 2013-07-04 19:05:10.000000000 +0530 +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c 2013-07-24 17:56:42.000000000 +0530 @@ -257,6 +257,11 @@ do { \ sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \ } while (0); +/* number of bytes needed to represent luns involved + * in mode select in bit string format + */ +#define LUN_FAILOVER_BYTES 32 + static inline struct rdac_dh_data *get_rdac_data(struct scsi_device *sdev) { struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data; @@ -295,7 +300,8 @@ static struct request *get_rdac_req(stru } static struct request *rdac_failover_get(struct scsi_device *sdev, - struct rdac_dh_data *h, struct list_head *list) + struct rdac_dh_data *h, struct list_head *list, + unsigned int *num_luns) { struct request *rq; struct rdac_mode_common *common; @@ -331,7 +337,10 @@ static struct request *rdac_failover_get common->rdac_options = RDAC_FORCED_QUIESENCE; list_for_each_entry(qdata, list, entry) { - lun_table[qdata->h->lun] = 0x81; + if (lun_table[qdata->h->lun] != 0x81) { + lun_table[qdata->h->lun] = 0x81; + (*num_luns)++; + } } /* get request for block layer packet command */ @@ -582,6 +591,77 @@ done: return err; } +/* encode luns involved in mode select into 256 bits string. + * decode logic for lun number set in each byte is as follows: + * lun number = number of bits before the current byte + + * position index [0-7] of the set bit in the current byte from R->L + */ +static void lun_table_bitstring(unsigned char *lun_table, + unsigned int lun_table_length, unsigned char *lun_str) +{ + u8 lun_bit_table[LUN_FAILOVER_BYTES] = {0}; + u8 pos = 0, ret, byte; + unsigned int lun; + + BUG_ON(lun_str == NULL); + + for (lun = 0; lun < lun_table_length; ++lun) { + if (lun_table[lun] == 0x81) + lun_bit_table[lun/8] |= (1 << (lun % 8)); + } + for (byte = 0; byte < LUN_FAILOVER_BYTES; ++byte) { + ret = snprintf(lun_str+pos, 3, "%02x", + lun_bit_table[byte]); + pos = pos+ret; + } + lun_str[pos] = '\0'; + return ; +} + +/* get lun id's in mode select in either bit encoded + * or plain string format based on number of luns batched + */ +static void lun_table_string(unsigned char *lun_table, + unsigned int lun_table_length, + unsigned char *lun_str, unsigned int num_luns) +{ + u8 ret; + unsigned int lun, pos = 0; + + BUG_ON(lun_str == NULL); + + /* prefer encoded bit string for large number or luns */ + if (num_luns > 16) { + lun_table_bitstring(lun_table, lun_table_length, lun_str); + } else { + for (lun = 0; lun < lun_table_length; ++lun) { + if (lun_table[lun] == 0x81) { + ret = snprintf(lun_str+pos, 4, "%d", lun); + lun_str[pos+ret] = ','; + pos = pos+ret+1; + } + } + lun_str[pos-1] = '\0'; + } + return ; +} + +/* get mode select lun table string for debug pusposes */ +static void get_ms_lunstring(struct rdac_controller *ctlr, + unsigned char *lun_str, unsigned int num_luns) +{ + if (likely(ctlr->use_ms10)) { + struct rdac_pg_expanded *rdac_pg = &ctlr->mode_select.expanded; + lun_table_string(&rdac_pg->lun_table[0], + 256, lun_str, num_luns); + } else { + struct rdac_pg_legacy *rdac_pg = &ctlr->mode_select.legacy; + lun_table_string(&rdac_pg->lun_table[0], + MODE6_MAX_LUN, lun_str, num_luns); + } + return ; +} + static void send_mode_select(struct work_struct *work) { struct rdac_controller *ctlr = @@ -592,6 +672,8 @@ static void send_mode_select(struct work struct request_queue *q = sdev->request_queue; int err, retry_cnt = RDAC_RETRY_COUNT; struct rdac_queue_data *tmp, *qdata; + unsigned int num_luns = 0; + unsigned char lun_str[LUN_FAILOVER_BYTES * 2 + 1] = {0}; LIST_HEAD(list); spin_lock(&ctlr->ms_lock); @@ -602,14 +684,19 @@ static void send_mode_select(struct work retry: err = SCSI_DH_RES_TEMP_UNAVAIL; - rq = rdac_failover_get(sdev, h, &list); + rq = rdac_failover_get(sdev, h, &list, &num_luns); if (!rq) goto done; + /* get lun debug string only once */ + if (retry_cnt == RDAC_RETRY_COUNT) + get_ms_lunstring(ctlr, lun_str, num_luns); + RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, " - "%s MODE_SELECT command", + "%s MODE_SELECT command for %d lun(s) [%s]", (char *) h->ctlr->array_name, h->ctlr->index, - (retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying"); + (retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : + "retrying", num_luns, lun_str); err = blk_execute_rq(q, NULL, rq, 1); blk_put_request(rq); @@ -621,8 +708,9 @@ retry: if (err == SCSI_DH_OK) { h->state = RDAC_STATE_ACTIVE; RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, " - "MODE_SELECT completed", - (char *) h->ctlr->array_name, h->ctlr->index); + "MODE_SELECT completed for %d lun(s) [%s]", + (char *) h->ctlr->array_name, h->ctlr->index, + num_luns, lun_str); } done: