From patchwork Thu Oct 11 18:30:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10637099 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9233A13AD for ; Thu, 11 Oct 2018 18:30:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 857372BEC0 for ; Thu, 11 Oct 2018 18:30:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 798C12BEEE; Thu, 11 Oct 2018 18:30:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DE9B12BEE1 for ; Thu, 11 Oct 2018 18:30:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729126AbeJLB7J (ORCPT ); Thu, 11 Oct 2018 21:59:09 -0400 Received: from mail-pl1-f194.google.com ([209.85.214.194]:41611 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729154AbeJLB7I (ORCPT ); Thu, 11 Oct 2018 21:59:08 -0400 Received: by mail-pl1-f194.google.com with SMTP id q17-v6so4633490plr.8 for ; Thu, 11 Oct 2018 11:30:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ERRnvUZIS8N8n63xlS85f/X0ts6OeeVqCOjS1np0D6g=; b=XbAFdY2LGtFEj6Oynf07bBgAZCVgHzbnSbZj5VitT/q9fDCfLccfNaaGDF4hju+1Cx G/HglCZ69hF5tybD3kllZEpfS5ISV6FmIjNCZtiSJ/rz91wWVZO7sB10f7WmCJcGXE99 Bhz/oRE3dD7Gkive3Ld+wVwv5yoteQs5ya4r+27P7By+K8FanBSMiGD9wMfekIx+wgGI OziNBNYJN3laY4qbQ74m6vZXNx8LDWjtkLMhopJUyURDPbVL9ZqL4BVf91M6qNx6Noyg vDq9SEmmLrX/uGJ0zEaxW4Y7wmJK6crC29SdWF3n7sz0YA96WAdfPlWvBlTvlY6V5v0L xMpA== 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:mime-version:content-transfer-encoding; bh=ERRnvUZIS8N8n63xlS85f/X0ts6OeeVqCOjS1np0D6g=; b=D/2sfUQLeHXCsXL7yYvXuXkIwyEiM8xrP0XbR4ESp+/QThddkUCRC6W/ObPCLsjwj7 12KDsqfJGni4MMlmNniOA4wY/4yWeqBWl1p2gQwNLCFUrPLBRBvrvE3h3DM2Y4NuXtu7 QSyMd19daJjHBU2orz3xsykj3xEZghlWMxpn9QnSVE3GLZYr4okkKr2I8IbClRBjn+wc OXIbxpCNpunwB0EJ/JdUyVI2CvvT2xKkmpLqKmx0H5tas8Oz4g4KzfH30fPxNWTJVNok HFplaGHSyvGcNmMgObWNLpw/30jdB5g5oYZQUC3V03X0pSprz+L1Zf3aaoUh3chV/VWW xvEg== X-Gm-Message-State: ABuFfohHjkFKvHk6CZO6pdu1OZhOfUJ0x3R99U73tbe2JvH0sqKOYggj qgyefbQdQO9Fy5eyXXvMkZyuLM53e0o= X-Google-Smtp-Source: ACcGV62UhvQss/cHCeyH9mNvXK3Q13Gf57CSFaosmMXjoGg5sptCcDT6C6+hVvP25GvAjKesY9J0KQ== X-Received: by 2002:a17:902:9047:: with SMTP id w7-v6mr2614669plz.4.1539282643885; Thu, 11 Oct 2018 11:30:43 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:200::5:2383]) by smtp.gmail.com with ESMTPSA id o2-v6sm57514640pfj.57.2018.10.11.11.30.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 Oct 2018 11:30:43 -0700 (PDT) From: Omar Sandoval To: linux-block@vger.kernel.org Cc: Jens Axboe , kernel-team@fb.com, Laurent Vivier Subject: [PATCH 08/13] amiflop: convert to blk-mq Date: Thu, 11 Oct 2018 11:30:18 -0700 Message-Id: X-Mailer: git-send-email 2.19.1 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval Straightforward conversion, just use the existing amiflop_lock to serialize access to the controller. Compile-tested only. Cc: Laurent Vivier Signed-off-by: Omar Sandoval --- drivers/block/amiflop.c | 127 +++++++++++++++------------------------- 1 file changed, 48 insertions(+), 79 deletions(-) diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index eef3b085e70a..e9c701f9b32b 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -201,6 +201,7 @@ struct amiga_floppy_struct { int dirty; /* true when trackbuf is not on disk */ int status; /* current error code for unit */ struct gendisk *gendisk; + struct blk_mq_tag_set tag_set; }; /* @@ -281,7 +282,6 @@ static volatile int selected = -1; /* currently selected drive */ static int writepending; static int writefromint; static char *raw_buf; -static int fdc_queue; static DEFINE_SPINLOCK(amiflop_lock); @@ -1454,76 +1454,20 @@ static int get_track(int drive, int track) return -1; } -/* - * Round-robin between our available drives, doing one request from each - */ -static struct request *set_next_request(void) +static blk_status_t amiflop_rw_cur_segment(struct amiga_floppy_struct *floppy, + struct request *rq) { - struct request_queue *q; - int cnt = FD_MAX_UNITS; - struct request *rq = NULL; - - /* Find next queue we can dispatch from */ - fdc_queue = fdc_queue + 1; - if (fdc_queue == FD_MAX_UNITS) - fdc_queue = 0; - - for(cnt = FD_MAX_UNITS; cnt > 0; cnt--) { - - if (unit[fdc_queue].type->code == FD_NODRIVE) { - if (++fdc_queue == FD_MAX_UNITS) - fdc_queue = 0; - continue; - } - - q = unit[fdc_queue].gendisk->queue; - if (q) { - rq = blk_fetch_request(q); - if (rq) - break; - } - - if (++fdc_queue == FD_MAX_UNITS) - fdc_queue = 0; - } - - return rq; -} - -static void redo_fd_request(void) -{ - struct request *rq; + int drive = floppy - unit; unsigned int cnt, block, track, sector; - int drive; - struct amiga_floppy_struct *floppy; char *data; - unsigned long flags; - blk_status_t err; - -next_req: - rq = set_next_request(); - if (!rq) { - /* Nothing left to do */ - return; - } - floppy = rq->rq_disk->private_data; - drive = floppy - unit; - -next_segment: - /* Here someone could investigate to be more efficient */ - for (cnt = 0, err = BLK_STS_OK; cnt < blk_rq_cur_sectors(rq); cnt++) { + for (cnt = 0; cnt < blk_rq_cur_sectors(rq); cnt++) { #ifdef DEBUG printk("fd: sector %ld + %d requested for %s\n", blk_rq_pos(rq), cnt, (rq_data_dir(rq) == READ) ? "read" : "write"); #endif block = blk_rq_pos(rq) + cnt; - if ((int)block > floppy->blocks) { - err = BLK_STS_IOERR; - break; - } - track = block / (floppy->dtype->sects * floppy->type->sect_mult); sector = block % (floppy->dtype->sects * floppy->type->sect_mult); data = bio_data(rq->bio) + 512 * cnt; @@ -1532,10 +1476,8 @@ static void redo_fd_request(void) "0x%08lx\n", track, sector, data); #endif - if (get_track(drive, track) == -1) { - err = BLK_STS_IOERR; - break; - } + if (get_track(drive, track) == -1) + return BLK_STS_IOERR; if (rq_data_dir(rq) == READ) { memcpy(data, floppy->trackbuf + sector * 512, 512); @@ -1543,31 +1485,42 @@ static void redo_fd_request(void) memcpy(floppy->trackbuf + sector * 512, data, 512); /* keep the drive spinning while writes are scheduled */ - if (!fd_motor_on(drive)) { - err = BLK_STS_IOERR; - break; - } + if (!fd_motor_on(drive)) + return BLK_STS_IOERR; /* * setup a callback to write the track buffer * after a short (1 tick) delay. */ - local_irq_save(flags); - floppy->dirty = 1; /* reset the timer */ mod_timer (flush_track_timer + drive, jiffies + 1); - local_irq_restore(flags); } } - if (__blk_end_request_cur(rq, err)) - goto next_segment; - goto next_req; + return BLK_STS_OK; } -static void do_fd_request(struct request_queue * q) +static blk_status_t amiflop_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - redo_fd_request(); + struct request *rq = bd->rq; + struct amiga_floppy_struct *floppy = rq->rq_disk->private_data; + blk_status_t err; + + if (!spin_trylock_irq(&amiflop_lock)) + return BLK_STS_DEV_RESOURCE; + + blk_mq_start_request(rq); + + do { + err = amiflop_rw_cur_segment(floppy, rq); + if (err) + break; + } while (blk_update_request(rq, err, blk_rq_cur_bytes(rq))); + blk_mq_end_request(rq, err); + + spin_unlock_irq(&amiflop_lock); + return BLK_STS_OK; } static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) @@ -1818,18 +1771,32 @@ static const struct block_device_operations floppy_fops = { .check_events = amiga_check_events, }; +static const struct blk_mq_ops amiflop_mq_ops = { + .queue_rq = amiflop_queue_rq, +}; + static struct gendisk *fd_alloc_disk(int drive) { struct gendisk *disk; + struct blk_mq_tag_set *set; disk = alloc_disk(1); if (!disk) goto out; - disk->queue = blk_init_queue(do_fd_request, &amiflop_lock); + set = &unit[drive].tag_set; + set->ops = &amiflop_mq_ops; + set->nr_hw_queues = 1; + set->queue_depth = 2; + set->numa_node = NUMA_NO_NODE; + set->flags = BLK_MQ_F_SHOULD_MERGE; + if (blk_mq_alloc_tag_set(set)) + goto out_put_disk; + + disk->queue = blk_mq_init_queue(set); if (IS_ERR(disk->queue)) { disk->queue = NULL; - goto out_put_disk; + goto out_free_tag_set; } unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL); @@ -1841,6 +1808,8 @@ static struct gendisk *fd_alloc_disk(int drive) out_cleanup_queue: blk_cleanup_queue(disk->queue); disk->queue = NULL; +out_free_tag_set: + blk_mq_free_tag_set(set); out_put_disk: put_disk(disk); out: