On Apr 23, 2013, at 12:02 AM, Alexander Motin <m...@freebsd.org> wrote:

> On 23.04.2013 05:35, Scott Long wrote:
>> What problem does this solve, other than to unintentionally break the MPT 
>> driver?  This needs to be backed out of HEAD and stable/9 until a better 
>> analysis is done.
> 
> It depends on definition of "problem". I don't think that polling in a tight 
> loop is a right way to do anything while system is operational.
> 

Breaking a common storage controller for nothing more than aesthetic reasons is 
a problem.  I'd like you to discuss and review this stuff more.  Please.  
Pretty, pretty please.

> Search through the sources shows that the only two drivers doing nasty things 
> on shutdown_post_sync are mpt and hptmv.  While hptmv really shuts worker 
> thread down there, mpt just disables interrupts breaking normal operation. 
> That situation looks quite dirty to me. From one side if controller really 
> needs shutdown (to flush some caches, etc), then it should not receive any 
> (or reject all) commands after that point (either polled or not). If it 
> doesn't need shutdown, then what for are these shaman dances?
> 

You'll need to talk to Gibbs about MPT.  I committed the code as a proxy for 
him; I don't recall why he specifically wanted to shut down interrupts there.  
Talking to him would be a good pre-commit action.

> Instead of revert, I propose this trivial non-invasive patch to fix the 
> problem by moving hptmv and mpt shutdown a bit later in shutdown order: 
> http://people.freebsd.org/~mav/post_sync.patch
> 

I'm fine with the concept, so long as it works.  Have you tested it?

(btw, sorry I missed this response earlier)

Thanks,
Scott

>> On Apr 18, 2013, at 3:44 AM, Alexander Motin <m...@freebsd.org> wrote:
>> 
>>> Author: mav
>>> Date: Thu Apr 18 09:44:00 2013
>>> New Revision: 249611
>>> URL: http://svnweb.freebsd.org/changeset/base/249611
>>> 
>>> Log:
>>>  MFC r248872, r249048:
>>>  Make pre-shutdown flush and spindown routines to not use 
>>> xpt_polled_action(),
>>>  but execute the commands in regular way.  There is no any reason to cook 
>>> CPU
>>>  while the system is still fully operational.  After this change polling in
>>>  CAM is used only for kernel dumping.
>>> 
>>> Modified:
>>>  stable/9/sys/cam/ata/ata_da.c
>>>  stable/9/sys/cam/scsi/scsi_da.c
>>> Directory Properties:
>>>  stable/9/sys/   (props changed)
>>> 
>>> Modified: stable/9/sys/cam/ata/ata_da.c
>>> ==============================================================================
>>> --- stable/9/sys/cam/ata/ata_da.c   Thu Apr 18 09:40:34 2013        
>>> (r249610)
>>> +++ stable/9/sys/cam/ata/ata_da.c   Thu Apr 18 09:44:00 2013        
>>> (r249611)
>>> @@ -1825,11 +1825,10 @@ adaflush(void)
>>> {
>>>     struct cam_periph *periph;
>>>     struct ada_softc *softc;
>>> +   union ccb *ccb;
>>>     int error;
>>> 
>>>     CAM_PERIPH_FOREACH(periph, &adadriver) {
>>> -           union ccb ccb;
>>> -
>>>             /* If we paniced with lock held - not recurse here. */
>>>             if (cam_periph_owned(periph))
>>>                     continue;
>>> @@ -1845,10 +1844,8 @@ adaflush(void)
>>>                     continue;
>>>             }
>>> 
>>> -           xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
>>> -
>>> -           ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
>>> -           cam_fill_ataio(&ccb.ataio,
>>> +           ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
>>> +           cam_fill_ataio(&ccb->ataio,
>>>                                 0,
>>>                                 adadone,
>>>                                 CAM_DIR_NONE,
>>> @@ -1856,20 +1853,17 @@ adaflush(void)
>>>                                 NULL,
>>>                                 0,
>>>                                 ada_default_timeout*1000);
>>> -
>>>             if (softc->flags & ADA_FLAG_CAN_48BIT)
>>> -                   ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0);
>>> +                   ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
>>>             else
>>> -                   ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
>>> -           xpt_polled_action(&ccb);
>>> +                   ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
>>> 
>>> -           error = cam_periph_error(&ccb,
>>> -               0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
>>> -           if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
>>> -                   cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
>>> -                       /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
>>> +           error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
>>> +               /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
>>> +               softc->disk->d_devstat);
>>>             if (error != 0)
>>>                     xpt_print(periph->path, "Synchronize cache failed\n");
>>> +           xpt_release_ccb(ccb);
>>>             cam_periph_unlock(periph);
>>>     }
>>> }
>>> @@ -1879,11 +1873,10 @@ adaspindown(uint8_t cmd, int flags)
>>> {
>>>     struct cam_periph *periph;
>>>     struct ada_softc *softc;
>>> +   union ccb *ccb;
>>>     int error;
>>> 
>>>     CAM_PERIPH_FOREACH(periph, &adadriver) {
>>> -           union ccb ccb;
>>> -
>>>             /* If we paniced with lock held - not recurse here. */
>>>             if (cam_periph_owned(periph))
>>>                     continue;
>>> @@ -1900,10 +1893,8 @@ adaspindown(uint8_t cmd, int flags)
>>>             if (bootverbose)
>>>                     xpt_print(periph->path, "spin-down\n");
>>> 
>>> -           xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
>>> -
>>> -           ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
>>> -           cam_fill_ataio(&ccb.ataio,
>>> +           ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
>>> +           cam_fill_ataio(&ccb->ataio,
>>>                                 0,
>>>                                 adadone,
>>>                                 CAM_DIR_NONE | flags,
>>> @@ -1911,17 +1902,14 @@ adaspindown(uint8_t cmd, int flags)
>>>                                 NULL,
>>>                                 0,
>>>                                 ada_default_timeout*1000);
>>> +           ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, 0);
>>> 
>>> -           ata_28bit_cmd(&ccb.ataio, cmd, 0, 0, 0);
>>> -           xpt_polled_action(&ccb);
>>> -
>>> -           error = cam_periph_error(&ccb,
>>> -               0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
>>> -           if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
>>> -                   cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
>>> -                       /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
>>> +           error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
>>> +               /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
>>> +               softc->disk->d_devstat);
>>>             if (error != 0)
>>>                     xpt_print(periph->path, "Spin-down disk failed\n");
>>> +           xpt_release_ccb(ccb);
>>>             cam_periph_unlock(periph);
>>>     }
>>> }
>>> 
>>> Modified: stable/9/sys/cam/scsi/scsi_da.c
>>> ==============================================================================
>>> --- stable/9/sys/cam/scsi/scsi_da.c Thu Apr 18 09:40:34 2013        
>>> (r249610)
>>> +++ stable/9/sys/cam/scsi/scsi_da.c Thu Apr 18 09:44:00 2013        
>>> (r249611)
>>> @@ -2834,11 +2834,10 @@ dashutdown(void * arg, int howto)
>>> {
>>>     struct cam_periph *periph;
>>>     struct da_softc *softc;
>>> +   union ccb *ccb;
>>>     int error;
>>> 
>>>     CAM_PERIPH_FOREACH(periph, &dadriver) {
>>> -           union ccb ccb;
>>> -
>>>             cam_periph_lock(periph);
>>>             softc = (struct da_softc *)periph->softc;
>>> 
>>> @@ -2852,10 +2851,8 @@ dashutdown(void * arg, int howto)
>>>                     continue;
>>>             }
>>> 
>>> -           xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
>>> -
>>> -           ccb.ccb_h.ccb_state = DA_CCB_DUMP;
>>> -           scsi_synchronize_cache(&ccb.csio,
>>> +           ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
>>> +           scsi_synchronize_cache(&ccb->csio,
>>>                                    /*retries*/0,
>>>                                    /*cbfcnp*/dadone,
>>>                                    MSG_SIMPLE_Q_TAG,
>>> @@ -2864,15 +2861,12 @@ dashutdown(void * arg, int howto)
>>>                                    SSD_FULL_SIZE,
>>>                                    60 * 60 * 1000);
>>> 
>>> -           xpt_polled_action(&ccb);
>>> -
>>> -           error = cam_periph_error(&ccb,
>>> -               0, SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, NULL);
>>> -           if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
>>> -                   cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
>>> -                       /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
>>> +           error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
>>> +               /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR,
>>> +               softc->disk->d_devstat);
>>>             if (error != 0)
>>>                     xpt_print(periph->path, "Synchronize cache failed\n");
>>> +           xpt_release_ccb(ccb);
>>>             cam_periph_unlock(periph);
>>>     }
>>> }
>> 
> 
> 
> -- 
> Alexander Motin

_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to