From owner-svn-src-head@FreeBSD.ORG Tue Jul 8 12:15:16 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 87E1D9D3; Tue, 8 Jul 2014 12:15:16 +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 5BA012BE7; Tue, 8 Jul 2014 12:15:16 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s68CFGPk037258; Tue, 8 Jul 2014 12:15:16 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s68CFGxj037257; Tue, 8 Jul 2014 12:15:16 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201407081215.s68CFGxj037257@svn.freebsd.org> From: Alexander Motin Date: Tue, 8 Jul 2014 12:15:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r268391 - head/sys/cam/ctl X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Jul 2014 12:15:16 -0000 Author: mav Date: Tue Jul 8 12:15:15 2014 New Revision: 268391 URL: http://svnweb.freebsd.org/changeset/base/268391 Log: Return task management requests to queued execution, but differently. Testing shown that both original queued design with separate task queue, and recent direct execution design had significant flaw: If abort request arrives just after the victim, the last one may not be in the ooa_queue yet, and so invisible for the task management function. Unlike original queued implementation, use same queue for all SCSI and TASK requests from the same initiator. That avoids races between them: task functions are always executed in proper time, relatively to other requests. Modified: head/sys/cam/ctl/ctl.c Modified: head/sys/cam/ctl/ctl.c ============================================================================== --- head/sys/cam/ctl/ctl.c Tue Jul 8 10:11:47 2014 (r268390) +++ head/sys/cam/ctl/ctl.c Tue Jul 8 12:15:15 2014 (r268391) @@ -12066,10 +12066,6 @@ ctl_abort_task(union ctl_io *io) return (0); } -/* - * This routine cannot block! It must be callable from an interrupt - * handler as well as from the work thread. - */ static void ctl_run_task(union ctl_io *io) { @@ -13690,10 +13686,8 @@ ctl_queue(union ctl_io *io) switch (io->io_hdr.io_type) { case CTL_IO_SCSI: - ctl_enqueue_incoming(io); - break; case CTL_IO_TASK: - ctl_run_task(io); + ctl_enqueue_incoming(io); break; default: printf("ctl_queue: unknown I/O type %d\n", io->io_hdr.io_type); @@ -13862,6 +13856,16 @@ ctl_work_thread(void *arg) retval = ctl_process_done(io); continue; } + io = (union ctl_io *)STAILQ_FIRST(&thr->incoming_queue); + if (io != NULL) { + STAILQ_REMOVE_HEAD(&thr->incoming_queue, links); + mtx_unlock(&thr->queue_lock); + if (io->io_hdr.io_type == CTL_IO_TASK) + ctl_run_task(io); + else + ctl_scsiio_precheck(softc, &io->scsiio); + continue; + } if (!ctl_pause_rtr) { io = (union ctl_io *)STAILQ_FIRST(&thr->rtr_queue); if (io != NULL) { @@ -13873,13 +13877,6 @@ ctl_work_thread(void *arg) continue; } } - io = (union ctl_io *)STAILQ_FIRST(&thr->incoming_queue); - if (io != NULL) { - STAILQ_REMOVE_HEAD(&thr->incoming_queue, links); - mtx_unlock(&thr->queue_lock); - ctl_scsiio_precheck(softc, &io->scsiio); - continue; - } /* Sleep until we have something to do. */ mtx_sleep(thr, &thr->queue_lock, PDROP | PRIBIO, "-", 0); @@ -13917,8 +13914,11 @@ ctl_enqueue_incoming(union ctl_io *io) { struct ctl_softc *softc = control_softc; struct ctl_thread *thr; + u_int idx; - thr = &softc->threads[io->io_hdr.nexus.targ_mapped_lun % worker_threads]; + idx = (io->io_hdr.nexus.targ_port * 127 + + io->io_hdr.nexus.initid.id) % worker_threads; + thr = &softc->threads[idx]; mtx_lock(&thr->queue_lock); STAILQ_INSERT_TAIL(&thr->incoming_queue, &io->io_hdr, links); mtx_unlock(&thr->queue_lock);