Re: [GIT PULL] s390 patches for 4.13 merge window

From: Stephen Rothwell
Date: Mon Jul 03 2017 - 15:41:05 EST


Hi all,

On Mon, 3 Jul 2017 11:01:34 +0200 Martin Schwidefsky <schwidefsky@xxxxxxxxxx> wrote:
>
> please pull from the 'for-linus' branch of
>
> git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git for-linus
>
> to receive the following updates:
>
> The bulk of the s390 patches for 4.13. Some new things but mostly
> bug fixes and cleanups. Noteworthy changes:
>
> * The SCM block driver is converted to blk-mq

It might have been nice to mention the conflict in this with the block
tree which I resolved like this:

diff --cc drivers/s390/block/scm_blk.c
index 725f912fab41,3c2c84b72877..0071febac9e6
--- a/drivers/s390/block/scm_blk.c
+++ b/drivers/s390/block/scm_blk.c
@@@ -228,12 -231,22 +228,12 @@@ static inline void scm_request_init(str
aob->request.data = (u64) aobrq;
scmrq->bdev = bdev;
scmrq->retries = 4;
- scmrq->error = 0;
+ scmrq->error = BLK_STS_OK;
/* We don't use all msbs - place aidaws at the end of the aob page. */
scmrq->next_aidaw = (void *) &aob->msb[nr_requests_per_io];
- scm_request_cluster_init(scmrq);
}

-static void scm_ensure_queue_restart(struct scm_blk_dev *bdev)
-{
- if (atomic_read(&bdev->queued_reqs)) {
- /* Queue restart is triggered by the next interrupt. */
- return;
- }
- blk_delay_queue(bdev->rq, SCM_QUEUE_DELAY);
-}
-
-void scm_request_requeue(struct scm_request *scmrq)
+static void scm_request_requeue(struct scm_request *scmrq)
{
struct scm_blk_dev *bdev = scmrq->bdev;
int i;
@@@ -271,83 -289,75 +271,83 @@@ static void scm_request_start(struct sc
SCM_LOG(5, "no subchannel");
scm_request_requeue(scmrq);
}
- return ret;
}

-static void scm_blk_request(struct request_queue *rq)
+struct scm_queue {
+ struct scm_request *scmrq;
+ spinlock_t lock;
+};
+
- static int scm_blk_request(struct blk_mq_hw_ctx *hctx,
++static blk_status_t scm_blk_request(struct blk_mq_hw_ctx *hctx,
+ const struct blk_mq_queue_data *qd)
{
- struct scm_device *scmdev = rq->queuedata;
+ struct scm_device *scmdev = hctx->queue->queuedata;
struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev);
- struct scm_request *scmrq = NULL;
- struct request *req;
+ struct scm_queue *sq = hctx->driver_data;
+ struct request *req = qd->rq;
+ struct scm_request *scmrq;

- while ((req = blk_peek_request(rq))) {
- if (!scm_permit_request(bdev, req))
- goto out;
+ spin_lock(&sq->lock);
+ if (!scm_permit_request(bdev, req)) {
+ spin_unlock(&sq->lock);
- return BLK_MQ_RQ_QUEUE_BUSY;
++ return BLK_STS_RESOURCE;
+ }

+ scmrq = sq->scmrq;
+ if (!scmrq) {
+ scmrq = scm_request_fetch();
if (!scmrq) {
- scmrq = scm_request_fetch();
- if (!scmrq) {
- SCM_LOG(5, "no request");
- goto out;
- }
- scm_request_init(bdev, scmrq);
+ SCM_LOG(5, "no request");
+ spin_unlock(&sq->lock);
- return BLK_MQ_RQ_QUEUE_BUSY;
++ return BLK_STS_RESOURCE;
}
- scm_request_set(scmrq, req);
+ scm_request_init(bdev, scmrq);
+ sq->scmrq = scmrq;
+ }
+ scm_request_set(scmrq, req);

- if (!scm_reserve_cluster(scmrq)) {
- SCM_LOG(5, "cluster busy");
- scm_request_set(scmrq, NULL);
- if (scmrq->aob->request.msb_count)
- goto out;
+ if (scm_request_prepare(scmrq)) {
+ SCM_LOG(5, "aidaw alloc failed");
+ scm_request_set(scmrq, NULL);

- scm_request_done(scmrq);
- return;
- }
+ if (scmrq->aob->request.msb_count)
+ scm_request_start(scmrq);

- if (scm_need_cluster_request(scmrq)) {
- if (scmrq->aob->request.msb_count) {
- /* Start cluster requests separately. */
- scm_request_set(scmrq, NULL);
- if (scm_request_start(scmrq))
- return;
- } else {
- atomic_inc(&bdev->queued_reqs);
- blk_start_request(req);
- scm_initiate_cluster_request(scmrq);
- }
- scmrq = NULL;
- continue;
- }
+ sq->scmrq = NULL;
+ spin_unlock(&sq->lock);
- return BLK_MQ_RQ_QUEUE_BUSY;
++ return BLK_STS_RESOURCE;
+ }
+ blk_mq_start_request(req);

- if (scm_request_prepare(scmrq)) {
- SCM_LOG(5, "aidaw alloc failed");
- scm_request_set(scmrq, NULL);
- goto out;
- }
- blk_start_request(req);
+ if (qd->last || scmrq->aob->request.msb_count == nr_requests_per_io) {
+ scm_request_start(scmrq);
+ sq->scmrq = NULL;
+ }
+ spin_unlock(&sq->lock);
- return BLK_MQ_RQ_QUEUE_OK;
++ return BLK_STS_OK;
+}

- if (scmrq->aob->request.msb_count < nr_requests_per_io)
- continue;
+static int scm_blk_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
+ unsigned int idx)
+{
+ struct scm_queue *qd = kzalloc(sizeof(*qd), GFP_KERNEL);

- if (scm_request_start(scmrq))
- return;
+ if (!qd)
+ return -ENOMEM;

- scmrq = NULL;
- }
-out:
- if (scmrq)
- scm_request_start(scmrq);
- else
- scm_ensure_queue_restart(bdev);
+ spin_lock_init(&qd->lock);
+ hctx->driver_data = qd;
+
+ return 0;
+}
+
+static void scm_blk_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int idx)
+{
+ struct scm_queue *qd = hctx->driver_data;
+
+ WARN_ON(qd->scmrq);
+ kfree(hctx->driver_data);
+ hctx->driver_data = NULL;
}

static void __scmrq_log_error(struct scm_request *scmrq)
@@@ -394,28 -419,43 +394,28 @@@ restart
return;

requeue:
- spin_lock_irqsave(&bdev->rq_lock, flags);
scm_request_requeue(scmrq);
- spin_unlock_irqrestore(&bdev->rq_lock, flags);
}

- void scm_blk_irq(struct scm_device *scmdev, void *data, int error)
-static void scm_blk_tasklet(struct scm_blk_dev *bdev)
++void scm_blk_irq(struct scm_device *scmdev, void *data, blk_status_t error)
{
- struct scm_request *scmrq;
- unsigned long flags;
-
- spin_lock_irqsave(&bdev->lock, flags);
- while (!list_empty(&bdev->finished_requests)) {
- scmrq = list_first_entry(&bdev->finished_requests,
- struct scm_request, list);
- list_del(&scmrq->list);
- spin_unlock_irqrestore(&bdev->lock, flags);
+ struct scm_request *scmrq = data;

- if (scmrq->error && scmrq->retries-- > 0) {
+ scmrq->error = error;
+ if (error) {
+ __scmrq_log_error(scmrq);
+ if (scmrq->retries-- > 0) {
scm_blk_handle_error(scmrq);
-
- /* Request restarted or requeued, handle next. */
- spin_lock_irqsave(&bdev->lock, flags);
- continue;
+ return;
}
+ }

- if (scm_test_cluster_request(scmrq)) {
- scm_cluster_request_irq(scmrq);
- spin_lock_irqsave(&bdev->lock, flags);
- continue;
- }
+ scm_request_finish(scmrq);
+}

- scm_request_finish(scmrq);
- spin_lock_irqsave(&bdev->lock, flags);
- }
- spin_unlock_irqrestore(&bdev->lock, flags);
- /* Look out for more requests. */
- blk_run_queue(bdev->rq);
+static void scm_blk_request_done(struct request *req)
+{
+ blk_mq_end_request(req, 0);
}

static const struct block_device_operations scm_blk_devops = {
diff --cc drivers/s390/block/scm_blk.h
index 242d17a91920,cd598d1a4eae..71288dd9dd7f
--- a/drivers/s390/block/scm_blk.h
+++ b/drivers/s390/block/scm_blk.h
@@@ -32,7 -35,14 +32,7 @@@ struct scm_request
struct aob *aob;
struct list_head list;
u8 retries;
- int error;
+ blk_status_t error;
-#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE
- struct {
- enum {CLUSTER_NONE, CLUSTER_READ, CLUSTER_WRITE} state;
- struct list_head list;
- void **buf;
- } cluster;
-#endif
};

#define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data)
@@@ -40,8 -50,11 +40,8 @@@
int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
void scm_blk_dev_cleanup(struct scm_blk_dev *);
void scm_blk_set_available(struct scm_blk_dev *);
- void scm_blk_irq(struct scm_device *, void *, int);
+ void scm_blk_irq(struct scm_device *, void *, blk_status_t);

-void scm_request_finish(struct scm_request *);
-void scm_request_requeue(struct scm_request *);
-
struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes);

int scm_drv_init(void);

--
Cheers,
Stephen Rothwell