tree:
https://git.kernel.org/pub/scm/linux/kernel/git/sashal/linux-stable.git
pending-5.4
head: 3e642124b47b335e4dcaf5e134fc3e865e5ec826
commit: b259d76fe4b3dd69bcb45ac9ab2b5b5dda0f1f78 [20/142] scsi: scsi_dh_alua: Check for
negative result value
config: microblaze-randconfig-m031-20210719 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 10.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
New smatch warnings:
drivers/scsi/device_handler/scsi_dh_alua.c:551 alua_rtpg() warn: unsigned 'retval'
is never less than zero.
Old smatch warnings:
drivers/scsi/device_handler/scsi_dh_alua.c:556 alua_rtpg() warn: unsigned 'retval'
is never less than zero.
vim +/retval +551 drivers/scsi/device_handler/scsi_dh_alua.c
496
497 /*
498 * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
499 * @sdev: the device to be evaluated.
500 *
501 * Evaluate the Target Port Group State.
502 * Returns SCSI_DH_DEV_OFFLINED if the path is
503 * found to be unusable.
504 */
505 static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
506 {
507 struct scsi_sense_hdr sense_hdr;
508 struct alua_port_group *tmp_pg;
509 int len, k, off, bufflen = ALUA_RTPG_SIZE;
510 unsigned char *desc, *buff;
511 unsigned err, retval;
512 unsigned int tpg_desc_tbl_off;
513 unsigned char orig_transition_tmo;
514 unsigned long flags;
515 bool transitioning_sense = false;
516
517 if (!pg->expiry) {
518 unsigned long transition_tmo = ALUA_FAILOVER_TIMEOUT * HZ;
519
520 if (pg->transition_tmo)
521 transition_tmo = pg->transition_tmo * HZ;
522
523 pg->expiry = round_jiffies_up(jiffies + transition_tmo);
524 }
525
526 buff = kzalloc(bufflen, GFP_KERNEL);
527 if (!buff)
528 return SCSI_DH_DEV_TEMP_BUSY;
529
530 retry:
531 err = 0;
532 retval = submit_rtpg(sdev, buff, bufflen, &sense_hdr, pg->flags);
533
534 if (retval) {
535 /*
536 * Some (broken) implementations have a habit of returning
537 * an error during things like firmware update etc.
538 * But if the target only supports active/optimized there's
539 * not much we can do; it's not that we can switch paths
540 * or anything.
541 * So ignore any errors to avoid spurious failures during
542 * path failover.
543 */
544 if ((pg->valid_states & ~TPGS_SUPPORT_OPTIMIZED) == 0) {
545 sdev_printk(KERN_INFO, sdev,
546 "%s: ignoring rtpg result %d\n",
547 ALUA_DH_NAME, retval);
548 kfree(buff);
549 return SCSI_DH_OK;
550 }
551 if (retval < 0 || !scsi_sense_valid(&sense_hdr)) {
552 sdev_printk(KERN_INFO, sdev,
553 "%s: rtpg failed, result %d\n",
554 ALUA_DH_NAME, retval);
555 kfree(buff);
556 if (retval < 0)
557 return SCSI_DH_DEV_TEMP_BUSY;
558 return SCSI_DH_IO;
559 }
560
561 /*
562 * submit_rtpg() has failed on existing arrays
563 * when requesting extended header info, and
564 * the array doesn't support extended headers,
565 * even though it shouldn't according to T10.
566 * The retry without rtpg_ext_hdr_req set
567 * handles this.
568 * Note: some arrays return a sense key of ILLEGAL_REQUEST
569 * with ASC 00h if they don't support the extended header.
570 */
571 if (!(pg->flags & ALUA_RTPG_EXT_HDR_UNSUPP) &&
572 sense_hdr.sense_key == ILLEGAL_REQUEST) {
573 pg->flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
574 goto retry;
575 }
576 /*
577 * If the array returns with 'ALUA state transition'
578 * sense code here it cannot return RTPG data during
579 * transition. So set the state to 'transitioning' directly.
580 */
581 if (sense_hdr.sense_key == NOT_READY &&
582 sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) {
583 transitioning_sense = true;
584 goto skip_rtpg;
585 }
586 /*
587 * Retry on any other UNIT ATTENTION occurred.
588 */
589 if (sense_hdr.sense_key == UNIT_ATTENTION)
590 err = SCSI_DH_RETRY;
591 if (err == SCSI_DH_RETRY &&
592 pg->expiry != 0 && time_before(jiffies, pg->expiry)) {
593 sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n",
594 ALUA_DH_NAME);
595 scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
596 kfree(buff);
597 return err;
598 }
599 sdev_printk(KERN_ERR, sdev, "%s: rtpg failed\n",
600 ALUA_DH_NAME);
601 scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
602 kfree(buff);
603 pg->expiry = 0;
604 return SCSI_DH_IO;
605 }
606
607 len = get_unaligned_be32(&buff[0]) + 4;
608
609 if (len > bufflen) {
610 /* Resubmit with the correct length */
611 kfree(buff);
612 bufflen = len;
613 buff = kmalloc(bufflen, GFP_KERNEL);
614 if (!buff) {
615 sdev_printk(KERN_WARNING, sdev,
616 "%s: kmalloc buffer failed\n",__func__);
617 /* Temporary failure, bypass */
618 pg->expiry = 0;
619 return SCSI_DH_DEV_TEMP_BUSY;
620 }
621 goto retry;
622 }
623
624 orig_transition_tmo = pg->transition_tmo;
625 if ((buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR && buff[5] != 0)
626 pg->transition_tmo = buff[5];
627 else
628 pg->transition_tmo = ALUA_FAILOVER_TIMEOUT;
629
630 if (orig_transition_tmo != pg->transition_tmo) {
631 sdev_printk(KERN_INFO, sdev,
632 "%s: transition timeout set to %d seconds\n",
633 ALUA_DH_NAME, pg->transition_tmo);
634 pg->expiry = jiffies + pg->transition_tmo * HZ;
635 }
636
637 if ((buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR)
638 tpg_desc_tbl_off = 8;
639 else
640 tpg_desc_tbl_off = 4;
641
642 for (k = tpg_desc_tbl_off, desc = buff + tpg_desc_tbl_off;
643 k < len;
644 k += off, desc += off) {
645 u16 group_id = get_unaligned_be16(&desc[2]);
646
647 spin_lock_irqsave(&port_group_lock, flags);
648 tmp_pg = alua_find_get_pg(pg->device_id_str, pg->device_id_len,
649 group_id);
650 spin_unlock_irqrestore(&port_group_lock, flags);
651 if (tmp_pg) {
652 if (spin_trylock_irqsave(&tmp_pg->lock, flags)) {
653 if ((tmp_pg == pg) ||
654 !(tmp_pg->flags & ALUA_PG_RUNNING)) {
655 struct alua_dh_data *h;
656
657 tmp_pg->state = desc[0] & 0x0f;
658 tmp_pg->pref = desc[0] >> 7;
659 rcu_read_lock();
660 list_for_each_entry_rcu(h,
661 &tmp_pg->dh_list, node) {
662 if (!h->sdev)
663 continue;
664 h->sdev->access_state = desc[0];
665 }
666 rcu_read_unlock();
667 }
668 if (tmp_pg == pg)
669 tmp_pg->valid_states = desc[1];
670 spin_unlock_irqrestore(&tmp_pg->lock, flags);
671 }
672 kref_put(&tmp_pg->kref, release_port_group);
673 }
674 off = 8 + (desc[7] * 4);
675 }
676
677 skip_rtpg:
678 spin_lock_irqsave(&pg->lock, flags);
679 if (transitioning_sense)
680 pg->state = SCSI_ACCESS_STATE_TRANSITIONING;
681
682 sdev_printk(KERN_INFO, sdev,
683 "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n",
684 ALUA_DH_NAME, pg->group_id, print_alua_state(pg->state),
685 pg->pref ? "preferred" : "non-preferred",
686 pg->valid_states&TPGS_SUPPORT_TRANSITION?'T':'t',
687 pg->valid_states&TPGS_SUPPORT_OFFLINE?'O':'o',
688 pg->valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l',
689 pg->valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u',
690 pg->valid_states&TPGS_SUPPORT_STANDBY?'S':'s',
691 pg->valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n',
692 pg->valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a');
693
694 switch (pg->state) {
695 case SCSI_ACCESS_STATE_TRANSITIONING:
696 if (time_before(jiffies, pg->expiry)) {
697 /* State transition, retry */
698 pg->interval = ALUA_RTPG_RETRY_DELAY;
699 err = SCSI_DH_RETRY;
700 } else {
701 struct alua_dh_data *h;
702
703 /* Transitioning time exceeded, set port to standby */
704 err = SCSI_DH_IO;
705 pg->state = SCSI_ACCESS_STATE_STANDBY;
706 pg->expiry = 0;
707 rcu_read_lock();
708 list_for_each_entry_rcu(h, &pg->dh_list, node) {
709 if (!h->sdev)
710 continue;
711 h->sdev->access_state =
712 (pg->state & SCSI_ACCESS_STATE_MASK);
713 if (pg->pref)
714 h->sdev->access_state |=
715 SCSI_ACCESS_STATE_PREFERRED;
716 }
717 rcu_read_unlock();
718 }
719 break;
720 case SCSI_ACCESS_STATE_OFFLINE:
721 /* Path unusable */
722 err = SCSI_DH_DEV_OFFLINED;
723 pg->expiry = 0;
724 break;
725 default:
726 /* Useable path if active */
727 err = SCSI_DH_OK;
728 pg->expiry = 0;
729 break;
730 }
731 spin_unlock_irqrestore(&pg->lock, flags);
732 kfree(buff);
733 return err;
734 }
735
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org