From patchwork Wed May 23 02:27:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Khalid Elmously X-Patchwork-Id: 918704 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40rGgV44bhz9s2k; Wed, 23 May 2018 12:29:42 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1fLJWx-0003An-8Q; Wed, 23 May 2018 02:29:35 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1fLJWt-00037O-1d for kernel-team@lists.ubuntu.com; Wed, 23 May 2018 02:29:31 +0000 Received: from mail-it0-f71.google.com ([209.85.214.71]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1fLJWs-0007sT-L2 for kernel-team@lists.ubuntu.com; Wed, 23 May 2018 02:29:30 +0000 Received: by mail-it0-f71.google.com with SMTP id r7-v6so1494604ith.5 for ; Tue, 22 May 2018 19:29:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9k1SxHWScouJC+NFmr6hkQahGmNyaTEHruvcO6V9eb4=; b=BCRiyflOq5orJoUnfqPyjv690ur2iHNRjjVDxU+dAzhqUvmYiHdKYm//t4PpDgAR/C VPGmeOi+mZ++O6aYU/1M3FTjygmhantxoiNnkeZxpvVDfaXEb5mGEthVJN1qAyWrKhHq 4Un0XcANSxjStoyl6JQbAvakZYXeycbXshND/FnWnfVzZwJRBZflra+f6MzlHBCccywr zxJkkhdphQE0KZz8/vJZRP9Mq+h/MwSKW2FhndCIBRHyqnqRdol0WmNugYbRRK7F5r0l rZuMwinpFemhgeBKRjh8EciXWE8jiih8HggVWXOS9lzdv20Mfk4D1fvqHdBTnk1YZ8dR m65g== X-Gm-Message-State: ALKqPwfuuUaVSQQtm7iv96uDc8mJ4rWIO/updv7ObgSNGFjDAuNYOqj9 1fVN/a4hay668urd97jMViPnlRfxekAcT/2sez5oUNrpjKPSEqZlQQ8pRKQd2Kkijh2Zi/div0y AiAgmlTZjtUFrDpE43ws8MNCfvjWd+kROr0h08bsc1A== X-Received: by 2002:a24:734b:: with SMTP id y72-v6mr3406114itb.56.1527042568947; Tue, 22 May 2018 19:29:28 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpAtDegTqqBXrOr8sSDg6YxlYunw+akp8oenCXlsDX3t0MMAObiIFcnGohHHJ+vmgxNigsCrg== X-Received: by 2002:a24:734b:: with SMTP id y72-v6mr3406106itb.56.1527042568748; Tue, 22 May 2018 19:29:28 -0700 (PDT) Received: from kbuntu.fuzzbuzz.org (198-84-180-15.cpe.teksavvy.com. [198.84.180.15]) by smtp.gmail.com with ESMTPSA id m16-v6sm9428605iob.69.2018.05.22.19.29.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 19:29:27 -0700 (PDT) From: Khalid Elmously To: kernel-team@lists.ubuntu.com Subject: [CVE-2017-18232][A][PATCH 08/11] scsi: libsas: Use new workqueue to run sas event and disco event Date: Tue, 22 May 2018 22:27:56 -0400 Message-Id: <20180523022759.22556-9-khalid.elmously@canonical.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180523022759.22556-1-khalid.elmously@canonical.com> References: <20180523022759.22556-1-khalid.elmously@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jason Yan CVE-2017-18232 Now all libsas works are queued to scsi host workqueue, include sas event work post by LLDD and sas discovery work, and a sas hotplug flow may be divided into several works, e.g libsas receive a PORTE_BYTES_DMAED event, currently we process it as following steps: sas_form_port --- run in work in shost workq sas_discover_domain --- run in another work in shost workq ... sas_probe_devices --- run in new work in shost workq We found during hot-add a device, libsas may need run several works in same workqueue to add device in system, the process is not atomic, it may interrupt by other sas event works, like PHYE_LOSS_OF_SIGNAL. This patch is preparation of execute libsas sas event in sync. We need to use different workqueue to run sas event and disco event. Otherwise the work will be blocked for waiting another chained work in the same workqueue. Signed-off-by: Yijing Wang CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams Signed-off-by: Jason Yan Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen (cherry-picked from 93bdbd06b1644ac15aa152e91faefed86cc04937 ) Signed-off-by: Khalid Elmously --- drivers/scsi/libsas/sas_discover.c | 2 +- drivers/scsi/libsas/sas_event.c | 6 +++--- drivers/scsi/libsas/sas_init.c | 18 ++++++++++++++++++ include/scsi/libsas.h | 3 +++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 60de66252fa2..14f714d05767 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -534,7 +534,7 @@ static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) * workqueue, or known to be submitted from a context that is * not racing against draining */ - scsi_queue_work(ha->core.shost, &sw->work); + queue_work(ha->disco_q, &sw->work); } static void sas_chain_event(int event, unsigned long *pending, diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index 7d0497614752..77ffb70f1914 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c @@ -40,7 +40,7 @@ int sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw) if (list_empty(&sw->drain_node)) list_add(&sw->drain_node, &ha->defer_q); } else - rc = scsi_queue_work(ha->core.shost, &sw->work); + rc = queue_work(ha->event_q, &sw->work); return rc; } @@ -61,7 +61,6 @@ static int sas_queue_event(int event, struct sas_work *work, void __sas_drain_work(struct sas_ha_struct *ha) { - struct workqueue_struct *wq = ha->core.shost->work_q; struct sas_work *sw, *_sw; int ret; @@ -70,7 +69,8 @@ void __sas_drain_work(struct sas_ha_struct *ha) spin_lock_irq(&ha->lock); spin_unlock_irq(&ha->lock); - drain_workqueue(wq); + drain_workqueue(ha->event_q); + drain_workqueue(ha->disco_q); spin_lock_irq(&ha->lock); clear_bit(SAS_HA_DRAINING, &ha->state); diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 811128eb0283..f9b0e8d9d309 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -109,6 +109,7 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr) int sas_register_ha(struct sas_ha_struct *sas_ha) { + char name[64]; int error = 0; mutex_init(&sas_ha->disco_mutex); @@ -142,10 +143,24 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) goto Undo_ports; } + error = -ENOMEM; + snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev)); + sas_ha->event_q = create_singlethread_workqueue(name); + if (!sas_ha->event_q) + goto Undo_ports; + + snprintf(name, sizeof(name), "%s_disco_q", dev_name(sas_ha->dev)); + sas_ha->disco_q = create_singlethread_workqueue(name); + if (!sas_ha->disco_q) + goto Undo_event_q; + INIT_LIST_HEAD(&sas_ha->eh_done_q); INIT_LIST_HEAD(&sas_ha->eh_ata_q); return 0; + +Undo_event_q: + destroy_workqueue(sas_ha->event_q); Undo_ports: sas_unregister_ports(sas_ha); Undo_phys: @@ -176,6 +191,9 @@ int sas_unregister_ha(struct sas_ha_struct *sas_ha) __sas_drain_work(sas_ha); mutex_unlock(&sas_ha->drain_mutex); + destroy_workqueue(sas_ha->disco_q); + destroy_workqueue(sas_ha->event_q); + return 0; } diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 0698768cb383..99e82f61a500 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -389,6 +389,9 @@ struct sas_ha_struct { struct device *dev; /* should be set */ struct module *lldd_module; /* should be set */ + struct workqueue_struct *event_q; + struct workqueue_struct *disco_q; + u8 *sas_addr; /* must be set */ u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE];