Linux block layer
 help / color / mirror / Atom feed
* Re: [PATCH v2 0/5] md: use bio_clone_fast()
From: Shaohua Li @ 2017-02-15 19:19 UTC (permalink / raw)
  To: Ming Lei
  Cc: Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown
In-Reply-To: <1487086143-10255-1-git-send-email-tom.leiming@gmail.com>

On Tue, Feb 14, 2017 at 11:28:58PM +0800, Ming Lei wrote:
> Hi,
> 
> This patches replaces bio_clone() with bio_fast_clone() in
> bio_clone_mddev() because:
> 
> 1) bio_clone_mddev() is used in raid normal I/O and isn't in
> resync I/O path, and all the direct access to bvec table in
> raid happens on resync I/O only except for write behind of raid1.
> Write behind is treated specially, so the replacement is safe.
> 
> 2) for write behind, bio_clone() is kept, but this patchset
> introduces bio_clone_bioset_partial() to just clone one specific 
> bvecs range instead of whole table. Then write behind is improved
> too.
> 
> V2:
> 	1) move 3rd patch into 2nd one
> 	2) kill  bio_clone_mddev() and use  bio_clone_fast() directly
> 	3) define local variable 'offset' as sector_t in raid1_write_request()
> 
> V1:
> 	1) don't introduce bio_clone_slow_mddev_partial()
> 	2) return failure if mddev->bio_set can't be created
> 	3) remove check in bio_clone_mddev() as suggested by
> 	Christoph Hellwig.
> 	4) rename bio_clone_mddev() as bio_clone_fast_mddev()

Applied, thanks!
 
> Ming Lei (5):
>   block: introduce bio_clone_bioset_partial()
>   md: fail if mddev->bio_set can't be created
>   md/raid1: use bio_clone_bioset_partial() in case of write behind
>   md: remove unnecessary check on mddev
>   md: fast clone bio in bio_clone_mddev()
> 
>  block/bio.c         | 61 +++++++++++++++++++++++++++++++++++++++++------------
>  drivers/md/faulty.c |  2 +-
>  drivers/md/md.c     | 15 ++++---------
>  drivers/md/md.h     |  2 --
>  drivers/md/raid1.c  | 28 +++++++++++++++++-------
>  drivers/md/raid10.c | 11 +++++-----
>  drivers/md/raid5.c  |  4 ++--
>  include/linux/bio.h | 11 ++++++++--
>  8 files changed, 89 insertions(+), 45 deletions(-)
> 
> -- 
> 2.7.4
> 

^ permalink raw reply

* Re: [PATCH 3/4] block/sed: Check received header lengths
From: Jon Derrick @ 2017-02-15 18:37 UTC (permalink / raw)
  To: Scott Bauer; +Cc: Rafael Antognolli, Jens Axboe, linux-block, linux-kernel
In-Reply-To: <20170215181542.GB3571@sbauer-Z170X-UD5>

On 02/15/2017 11:15 AM, Scott Bauer wrote:
> On Wed, Feb 15, 2017 at 12:38:53PM -0700, Jon Derrick wrote:
>> Add a buffer size check against discovery and response header lengths
>> before we loop over their buffers.
>>
>> Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
>> ---
>>  block/sed-opal.c | 35 +++++++++++++++++++++--------------
>>  1 file changed, 21 insertions(+), 14 deletions(-)
>>
>> diff --git a/block/sed-opal.c b/block/sed-opal.c
>> index d6dd604..addf89e 100644
>> --- a/block/sed-opal.c
>> +++ b/block/sed-opal.c
>> @@ -340,10 +340,17 @@ static int opal_discovery0_end(struct opal_dev *dev)
>>  	const struct d0_header *hdr = (struct d0_header *)dev->resp;
>>  	const u8 *epos = dev->resp, *cpos = dev->resp;
>>  	u16 comid = 0;
>> +	u32 hlen = be32_to_cpu(hdr->length);
>>  
>> -	print_buffer(dev->resp, be32_to_cpu(hdr->length));
>> +	print_buffer(dev->resp, hlen);
>>  
>> -	epos += be32_to_cpu(hdr->length); /* end of buffer */
>> +	if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
>> +		pr_warn("Discovery length overflows buffer (%zu+%u)/%u\n",
>> +			sizeof(*hdr), hlen, IO_BUFFER_LENGTH);
>> +		return -EFAULT;
>> +	}
>> +
>> +	epos += hlen; /* end of buffer */
>>  	cpos += sizeof(*hdr); /* current position on buffer */
>>  
>>  	while (cpos < epos && supported) {
>> @@ -713,6 +720,7 @@ static int response_parse(const u8 *buf, size_t length,
>>  	int total;
>>  	ssize_t token_length;
>>  	const u8 *pos;
>> +	u32 clen, plen, slen;
>>  
>>  	if (!buf)
>>  		return -EFAULT;
>> @@ -724,17 +732,16 @@ static int response_parse(const u8 *buf, size_t length,
>>  	pos = buf;
>>  	pos += sizeof(*hdr);
>>  
>> -	pr_debug("Response size: cp: %d, pkt: %d, subpkt: %d\n",
>> -		 be32_to_cpu(hdr->cp.length),
>> -		 be32_to_cpu(hdr->pkt.length),
>> -		 be32_to_cpu(hdr->subpkt.length));
>> -
>> -	if (hdr->cp.length == 0 || hdr->pkt.length == 0 ||
>> -	    hdr->subpkt.length == 0) {
>> -		pr_err("Bad header length. cp: %d, pkt: %d, subpkt: %d\n",
>> -		       be32_to_cpu(hdr->cp.length),
>> -		       be32_to_cpu(hdr->pkt.length),
>> -		       be32_to_cpu(hdr->subpkt.length));
>> +	clen = be32_to_cpu(hdr->cp.length);
>> +	plen = be32_to_cpu(hdr->pkt.length);
>> +	slen = be32_to_cpu(hdr->subpkt.length);
>> +	pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
>> +		 clen, plen, slen);
>> +
>> +	if (clen == 0 || plen == 0 || slen == 0 ||
>> +	    (u64)clen + plen + slen > IO_BUFFER_LENGTH) {
> 
> I think we're over calculating here. From my understanding of the spec:
> TCG_Storage_Architecture_Core_Spec_v2.01_r1.00.pdf
> 3.2.3
>   ComPackets, Packets & Subpackets
> 
> The Comp packet size should the size of the packet, and the subpackets.
> The "packet" should be the size of all the subpackets.
> And lastly the subpacket should be the size its payload.
Yep I forgot that. Good catch!


> 
> if ((u64) slen + sizeof(*hdr) > IO_BUFFER_LENGTH)
> 
> Since we never need the com packet length or pkt length (we never use them
> anywhere) I think the above check is okay. Let me know if i'm wrong though,
> or you have a different understanding of the lengths.
Agreed

> 
> 
> 
> 
> 
> 
> 
> 

^ permalink raw reply

* Re: [PATCH 3/4] block/sed: Check received header lengths
From: Scott Bauer @ 2017-02-15 18:15 UTC (permalink / raw)
  To: Jon Derrick; +Cc: Rafael Antognolli, Jens Axboe, linux-block, linux-kernel
In-Reply-To: <1487187535-10503-3-git-send-email-jonathan.derrick@intel.com>

On Wed, Feb 15, 2017 at 12:38:53PM -0700, Jon Derrick wrote:
> Add a buffer size check against discovery and response header lengths
> before we loop over their buffers.
> 
> Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
> ---
>  block/sed-opal.c | 35 +++++++++++++++++++++--------------
>  1 file changed, 21 insertions(+), 14 deletions(-)
> 
> diff --git a/block/sed-opal.c b/block/sed-opal.c
> index d6dd604..addf89e 100644
> --- a/block/sed-opal.c
> +++ b/block/sed-opal.c
> @@ -340,10 +340,17 @@ static int opal_discovery0_end(struct opal_dev *dev)
>  	const struct d0_header *hdr = (struct d0_header *)dev->resp;
>  	const u8 *epos = dev->resp, *cpos = dev->resp;
>  	u16 comid = 0;
> +	u32 hlen = be32_to_cpu(hdr->length);
>  
> -	print_buffer(dev->resp, be32_to_cpu(hdr->length));
> +	print_buffer(dev->resp, hlen);
>  
> -	epos += be32_to_cpu(hdr->length); /* end of buffer */
> +	if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
> +		pr_warn("Discovery length overflows buffer (%zu+%u)/%u\n",
> +			sizeof(*hdr), hlen, IO_BUFFER_LENGTH);
> +		return -EFAULT;
> +	}
> +
> +	epos += hlen; /* end of buffer */
>  	cpos += sizeof(*hdr); /* current position on buffer */
>  
>  	while (cpos < epos && supported) {
> @@ -713,6 +720,7 @@ static int response_parse(const u8 *buf, size_t length,
>  	int total;
>  	ssize_t token_length;
>  	const u8 *pos;
> +	u32 clen, plen, slen;
>  
>  	if (!buf)
>  		return -EFAULT;
> @@ -724,17 +732,16 @@ static int response_parse(const u8 *buf, size_t length,
>  	pos = buf;
>  	pos += sizeof(*hdr);
>  
> -	pr_debug("Response size: cp: %d, pkt: %d, subpkt: %d\n",
> -		 be32_to_cpu(hdr->cp.length),
> -		 be32_to_cpu(hdr->pkt.length),
> -		 be32_to_cpu(hdr->subpkt.length));
> -
> -	if (hdr->cp.length == 0 || hdr->pkt.length == 0 ||
> -	    hdr->subpkt.length == 0) {
> -		pr_err("Bad header length. cp: %d, pkt: %d, subpkt: %d\n",
> -		       be32_to_cpu(hdr->cp.length),
> -		       be32_to_cpu(hdr->pkt.length),
> -		       be32_to_cpu(hdr->subpkt.length));
> +	clen = be32_to_cpu(hdr->cp.length);
> +	plen = be32_to_cpu(hdr->pkt.length);
> +	slen = be32_to_cpu(hdr->subpkt.length);
> +	pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
> +		 clen, plen, slen);
> +
> +	if (clen == 0 || plen == 0 || slen == 0 ||
> +	    (u64)clen + plen + slen > IO_BUFFER_LENGTH) {

I think we're over calculating here. From my understanding of the spec:
TCG_Storage_Architecture_Core_Spec_v2.01_r1.00.pdf
3.2.3
  ComPackets, Packets & Subpackets

The Comp packet size should the size of the packet, and the subpackets.
The "packet" should be the size of all the subpackets.
And lastly the subpacket should be the size its payload.

if ((u64) slen + sizeof(*hdr) > IO_BUFFER_LENGTH)

Since we never need the com packet length or pkt length (we never use them
anywhere) I think the above check is okay. Let me know if i'm wrong though,
or you have a different understanding of the lengths.

^ permalink raw reply

* Re: [PATCH] blk-mq-sched: don't hold queue_lock when calling exit_icq
From: Jens Axboe @ 2017-02-15 18:04 UTC (permalink / raw)
  To: Paolo Valente, Omar Sandoval; +Cc: linux-block, kernel-team
In-Reply-To: <a3e62a57-d401-99e0-6487-fc8277204e71@fb.com>

On 02/15/2017 10:58 AM, Jens Axboe wrote:
> On 02/15/2017 10:24 AM, Paolo Valente wrote:
>>
>>> Il giorno 10 feb 2017, alle ore 19:32, Omar Sandoval <osandov@osandov.com> ha scritto:
>>>
>>> From: Omar Sandoval <osandov@fb.com>
>>>
>>> None of the other blk-mq elevator hooks are called with this lock held.
>>> Additionally, it can lead to circular locking dependencies between
>>> queue_lock and the private scheduler lock.
>>>
>>
>> Hi Omar,
>> I'm sorry but it seems that a new potential deadlock has showed up.
>> See lockdep splat below.
>>
>> I've tried to think about different solutions than turning back to
>> deferring the body of exit_icq, but at no avail.
> 
> Looks like a interaction between bfqd->lock and q->queue_lock. Since the
> core has no notion of you bfqd->lock, the naturally dependency here
> would be to nest bfqd->lock inside q->queue_lock. Is that possible for
> you?
> 
> Looking at the code a bit, maybe it'd just be simpler to get rid of
> holding the queue lock for that spot. For the mq scheduler, we really
> don't want places where we invoke with that held already. Does the below
> work for you?

Would need to remove one more lockdep assert. And only test this for
the mq parts, we'd need to spread a bit of love on the classic
scheduling icq exit path for this to work on that side.

diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index b12f9c87b4c3..546ff8f81ede 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -54,7 +54,7 @@ static void ioc_exit_icq(struct io_cq *icq)
 	icq->flags |= ICQ_EXITED;
 }
 
-/* Release an icq.  Called with both ioc and q locked. */
+/* Release an icq.  Called with ioc locked. */
 static void ioc_destroy_icq(struct io_cq *icq)
 {
 	struct io_context *ioc = icq->ioc;
@@ -62,7 +62,6 @@ static void ioc_destroy_icq(struct io_cq *icq)
 	struct elevator_type *et = q->elevator->type;
 
 	lockdep_assert_held(&ioc->lock);
-	lockdep_assert_held(q->queue_lock);
 
 	radix_tree_delete(&ioc->icq_tree, icq->q->id);
 	hlist_del_init(&icq->ioc_node);
@@ -222,25 +221,34 @@ void exit_io_context(struct task_struct *task)
 	put_io_context_active(ioc);
 }
 
+static void __ioc_clear_queue(struct list_head *icq_list)
+{
+	while (!list_empty(icq_list)) {
+		struct io_cq *icq = list_entry(icq_list->next,
+					       struct io_cq, q_node);
+		struct io_context *ioc = icq->ioc;
+
+		spin_lock_irq(&ioc->lock);
+		ioc_destroy_icq(icq);
+		spin_unlock_irq(&ioc->lock);
+	}
+}
+
 /**
  * ioc_clear_queue - break any ioc association with the specified queue
  * @q: request_queue being cleared
  *
- * Walk @q->icq_list and exit all io_cq's.  Must be called with @q locked.
+ * Walk @q->icq_list and exit all io_cq's.
  */
 void ioc_clear_queue(struct request_queue *q)
 {
-	lockdep_assert_held(q->queue_lock);
+	LIST_HEAD(icq_list);
 
-	while (!list_empty(&q->icq_list)) {
-		struct io_cq *icq = list_entry(q->icq_list.next,
-					       struct io_cq, q_node);
-		struct io_context *ioc = icq->ioc;
+	spin_lock_irq(q->queue_lock);
+	list_splice_init(&q->icq_list, &icq_list);
+	spin_unlock_irq(q->queue_lock);
 
-		spin_lock(&ioc->lock);
-		ioc_destroy_icq(icq);
-		spin_unlock(&ioc->lock);
-	}
+	__ioc_clear_queue(&icq_list);
 }
 
 int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 070d81bae1d5..1944aa1cb899 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -815,9 +815,7 @@ static void blk_release_queue(struct kobject *kobj)
 	blkcg_exit_queue(q);
 
 	if (q->elevator) {
-		spin_lock_irq(q->queue_lock);
 		ioc_clear_queue(q);
-		spin_unlock_irq(q->queue_lock);
 		elevator_exit(q->elevator);
 	}
 
diff --git a/block/elevator.c b/block/elevator.c
index a25bdd90b270..aaa1e9836512 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -985,9 +985,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
 		if (old_registered)
 			elv_unregister_queue(q);
 
-		spin_lock_irq(q->queue_lock);
 		ioc_clear_queue(q);
-		spin_unlock_irq(q->queue_lock);
 	}
 
 	/* allocate, init and register new elevator */

-- 
Jens Axboe

^ permalink raw reply related

* Re: [PATCH] blk-mq-sched: don't hold queue_lock when calling exit_icq
From: Jens Axboe @ 2017-02-15 17:58 UTC (permalink / raw)
  To: Paolo Valente, Omar Sandoval; +Cc: linux-block, kernel-team
In-Reply-To: <A71AF11B-8A3A-42A5-845A-B9FBEEF74FBA@linaro.org>

On 02/15/2017 10:24 AM, Paolo Valente wrote:
> 
>> Il giorno 10 feb 2017, alle ore 19:32, Omar Sandoval <osandov@osandov.com> ha scritto:
>>
>> From: Omar Sandoval <osandov@fb.com>
>>
>> None of the other blk-mq elevator hooks are called with this lock held.
>> Additionally, it can lead to circular locking dependencies between
>> queue_lock and the private scheduler lock.
>>
> 
> Hi Omar,
> I'm sorry but it seems that a new potential deadlock has showed up.
> See lockdep splat below.
> 
> I've tried to think about different solutions than turning back to
> deferring the body of exit_icq, but at no avail.

Looks like a interaction between bfqd->lock and q->queue_lock. Since the
core has no notion of you bfqd->lock, the naturally dependency here
would be to nest bfqd->lock inside q->queue_lock. Is that possible for
you?

Looking at the code a bit, maybe it'd just be simpler to get rid of
holding the queue lock for that spot. For the mq scheduler, we really
don't want places where we invoke with that held already. Does the below
work for you?


diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index b12f9c87b4c3..0f50b1296cf9 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -222,25 +222,34 @@ void exit_io_context(struct task_struct *task)
 	put_io_context_active(ioc);
 }
 
+static void __ioc_clear_queue(struct list_head *icq_list)
+{
+	while (!list_empty(icq_list)) {
+		struct io_cq *icq = list_entry(icq_list->next,
+					       struct io_cq, q_node);
+		struct io_context *ioc = icq->ioc;
+
+		spin_lock_irq(&ioc->lock);
+		ioc_destroy_icq(icq);
+		spin_unlock_irq(&ioc->lock);
+	}
+}
+
 /**
  * ioc_clear_queue - break any ioc association with the specified queue
  * @q: request_queue being cleared
  *
- * Walk @q->icq_list and exit all io_cq's.  Must be called with @q locked.
+ * Walk @q->icq_list and exit all io_cq's.
  */
 void ioc_clear_queue(struct request_queue *q)
 {
-	lockdep_assert_held(q->queue_lock);
+	LIST_HEAD(icq_list);
 
-	while (!list_empty(&q->icq_list)) {
-		struct io_cq *icq = list_entry(q->icq_list.next,
-					       struct io_cq, q_node);
-		struct io_context *ioc = icq->ioc;
+	spin_lock_irq(q->queue_lock);
+	list_splice_init(&q->icq_list, &icq_list);
+	spin_unlock_irq(q->queue_lock);
 
-		spin_lock(&ioc->lock);
-		ioc_destroy_icq(icq);
-		spin_unlock(&ioc->lock);
-	}
+	__ioc_clear_queue(&icq_list);
 }
 
 int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 070d81bae1d5..1944aa1cb899 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -815,9 +815,7 @@ static void blk_release_queue(struct kobject *kobj)
 	blkcg_exit_queue(q);
 
 	if (q->elevator) {
-		spin_lock_irq(q->queue_lock);
 		ioc_clear_queue(q);
-		spin_unlock_irq(q->queue_lock);
 		elevator_exit(q->elevator);
 	}
 
diff --git a/block/elevator.c b/block/elevator.c
index a25bdd90b270..aaa1e9836512 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -985,9 +985,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
 		if (old_registered)
 			elv_unregister_queue(q);
 
-		spin_lock_irq(q->queue_lock);
 		ioc_clear_queue(q);
-		spin_unlock_irq(q->queue_lock);
 	}
 
 	/* allocate, init and register new elevator */

-- 
Jens Axboe

^ permalink raw reply related

* Re: [PATCH] blk-mq-sched: don't hold queue_lock when calling exit_icq
From: Paolo Valente @ 2017-02-15 17:24 UTC (permalink / raw)
  To: Omar Sandoval; +Cc: Jens Axboe, linux-block, kernel-team
In-Reply-To: <73cd0cf484e8b75a771d908c172cd3a931dc00a3.1486751329.git.osandov@fb.com>


> Il giorno 10 feb 2017, alle ore 19:32, Omar Sandoval =
<osandov@osandov.com> ha scritto:
>=20
> From: Omar Sandoval <osandov@fb.com>
>=20
> None of the other blk-mq elevator hooks are called with this lock =
held.
> Additionally, it can lead to circular locking dependencies between
> queue_lock and the private scheduler lock.
>=20

Hi Omar,
I'm sorry but it seems that a new potential deadlock has showed up.
See lockdep splat below.

I've tried to think about different solutions than turning back to
deferring the body of exit_icq, but at no avail.

Thanks,
Paolo

[  138.167021] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D
[  138.182073] [ INFO: possible circular locking dependency detected ]
[  138.185012] 4.10.0-rc5-bfq-mq+ #42 Not tainted
[  138.219651] -------------------------------------------------------
[  138.261149] aggthr-with-gre/2170 is trying to acquire lock:
[  138.313137]  (&(&bfqd->lock)->rlock){-.-...}, at: =
[<ffffffff84484435>] bfq_exit_icq_bfqq+0x55/0x140
[  138.364973]=20
[  138.364973] but task is already holding lock:
[  138.416588]  (&(&ioc->lock)->rlock){-.....}, at: [<ffffffff84447828>] =
ioc_clear_queue+0x48/0xa0
[  138.484352]=20
[  138.484352] which lock already depends on the new lock.
[  138.484352]=20
[  138.536768]=20
[  138.536768] the existing dependency chain (in reverse order) is:
[  138.599738]=20
[  138.599738] -> #2 (&(&ioc->lock)->rlock){-.....}:
[  138.650975]       =20
[  138.650981] [<ffffffff840ee6bb>] lock_acquire+0x11b/0x220
[  138.711657]       =20
[  138.711661] [<ffffffff8494324d>] _raw_spin_lock+0x3d/0x80
[  138.763924]       =20
[  138.763930] [<ffffffff84447af2>] ioc_create_icq+0x92/0x1a0
[  138.819460]       =20
[  138.819465] [<ffffffff84454619>] blk_mq_sched_get_request+0x359/0x370
[  138.875819]       =20
[  138.875824] [<ffffffff8444e950>] blk_sq_make_request+0x130/0xa50
[  138.923681]       =20
[  138.923688] [<ffffffff844408e6>] generic_make_request+0xf6/0x2b0
[  138.991605]       =20
[  138.991611] [<ffffffff84440b13>] submit_bio+0x73/0x150
[  139.041088]       =20
[  139.041094] [<ffffffff842b2aec>] submit_bh_wbc+0x14c/0x180
[  139.083607]       =20
[  139.083613] [<ffffffff842b35ff>] block_read_full_page+0x27f/0x370
[  139.124926]       =20
[  139.124932] [<ffffffff842b68b8>] blkdev_readpage+0x18/0x20
[  139.176346]       =20
[  139.176352] [<ffffffff841da963>] do_read_cache_page+0x313/0x590
[  139.177482]       =20
[  139.177484] [<ffffffff841dabf5>] read_cache_page+0x15/0x20
[  139.178550]       =20
[  139.178552] [<ffffffff84459285>] read_dev_sector+0x75/0xd0
[  139.179650]       =20
[  139.179652] [<ffffffff84461b4b>] read_lba+0x17b/0x260
[  139.180653]       =20
[  139.180655] [<ffffffff84462412>] efi_partition+0xf2/0x7c0
[  139.181708]       =20
[  139.181709] [<ffffffff8445bb4d>] check_partition+0x13d/0x220
[  139.182792]       =20
[  139.182794] [<ffffffff84459b60>] rescan_partitions+0xc0/0x380
[  139.183911]       =20
[  139.183914] [<ffffffff842b7cce>] __blkdev_get+0x3ae/0x4f0
[  139.184971]       =20
[  139.184972] [<ffffffff842b80fc>] blkdev_get+0x14c/0x3b0
[  139.186016]       =20
[  139.186018] [<ffffffff8445823f>] device_add_disk+0x45f/0x4f0
[  139.212232]       =20
[  139.212238] [<ffffffff8469da20>] sd_probe_async+0x110/0x1c0
[  139.223160]       =20
[  139.223165] [<ffffffff840bc327>] async_run_entry_fn+0x37/0x150
[  139.224742]       =20
[  139.224747] [<ffffffff840b1087>] process_one_work+0x207/0x750
[  139.235800]       =20
[  139.235809] [<ffffffff840b161b>] worker_thread+0x4b/0x4f0
[  139.236878]       =20
[  139.236880] [<ffffffff840b863f>] kthread+0x10f/0x150
[  139.237878]       =20
[  139.237881] [<ffffffff84944271>] ret_from_fork+0x31/0x40
[  139.238938]=20
[  139.238938] -> #1 (&(&q->__queue_lock)->rlock){-.....}:
[  139.239882]       =20
[  139.239885] [<ffffffff840ee6bb>] lock_acquire+0x11b/0x220
[  139.240945]       =20
[  139.240948] [<ffffffff84943e66>] _raw_spin_lock_irqsave+0x56/0x90
[  139.242117]       =20
[  139.242120] [<ffffffff84482645>] bfq_bic_lookup.isra.112+0x25/0x60
[  139.243333]       =20
[  139.243338] [<ffffffff844827bd>] bfq_request_merge+0x3d/0xe0
[  139.244427]       =20
[  139.244430] [<ffffffff84439b8f>] elv_merge+0xcf/0xe0
[  139.245416]       =20
[  139.245419] [<ffffffff84453ff6>] blk_mq_sched_try_merge+0x36/0x150
[  139.246599]       =20
[  139.246602] [<ffffffff8447feea>] bfq_bio_merge+0x5a/0xa0
[  139.247662]       =20
[  139.247665] [<ffffffff844548b0>] __blk_mq_sched_bio_merge+0x60/0x70
[  139.248839]       =20
[  139.248841] [<ffffffff8444ea94>] blk_sq_make_request+0x274/0xa50
[  139.250007]       =20
[  139.250011] [<ffffffff844408e6>] generic_make_request+0xf6/0x2b0
[  139.251156]       =20
[  139.251159] [<ffffffff84440b13>] submit_bio+0x73/0x150
[  139.252230]       =20
[  139.252234] [<ffffffff842b2aec>] submit_bh_wbc+0x14c/0x180
[  139.253306]       =20
[  139.253310] [<ffffffff842b35ff>] block_read_full_page+0x27f/0x370
[  139.254465]       =20
[  139.254467] [<ffffffff842b68b8>] blkdev_readpage+0x18/0x20
[  139.279873]       =20
[  139.279880] [<ffffffff841da963>] do_read_cache_page+0x313/0x590
[  139.281035]       =20
[  139.281036] [<ffffffff841dabf5>] read_cache_page+0x15/0x20
[  139.282111]       =20
[  139.282113] [<ffffffff84459285>] read_dev_sector+0x75/0xd0
[  139.283199]       =20
[  139.283201] [<ffffffff84461b4b>] read_lba+0x17b/0x260
[  139.284226]       =20
[  139.284228] [<ffffffff84462412>] efi_partition+0xf2/0x7c0
[  139.285336]       =20
[  139.285339] [<ffffffff8445bb4d>] check_partition+0x13d/0x220
[  139.286437]       =20
[  139.286439] [<ffffffff84459b60>] rescan_partitions+0xc0/0x380
[  139.287566]       =20
[  139.287568] [<ffffffff842b7cce>] __blkdev_get+0x3ae/0x4f0
[  139.288633]       =20
[  139.288635] [<ffffffff842b80fc>] blkdev_get+0x14c/0x3b0
[  139.289671]       =20
[  139.289672] [<ffffffff8445823f>] device_add_disk+0x45f/0x4f0
[  139.291916]       =20
[  139.291919] [<ffffffff8469da20>] sd_probe_async+0x110/0x1c0
[  139.293003]       =20
[  139.293005] [<ffffffff840bc327>] async_run_entry_fn+0x37/0x150
[  139.294126]       =20
[  139.294128] [<ffffffff840b1087>] process_one_work+0x207/0x750
[  139.295245]       =20
[  139.295247] [<ffffffff840b161b>] worker_thread+0x4b/0x4f0
[  139.296317]       =20
[  139.296319] [<ffffffff840b863f>] kthread+0x10f/0x150
[  139.301536]       =20
[  139.301539] [<ffffffff84944271>] ret_from_fork+0x31/0x40
[  139.316757]=20
[  139.316757] -> #0 (&(&bfqd->lock)->rlock){-.-...}:
[  139.317633]       =20
[  139.317638] [<ffffffff840edd24>] __lock_acquire+0x15e4/0x1890
[  139.318738]       =20
[  139.318747] [<ffffffff840ee6bb>] lock_acquire+0x11b/0x220
[  139.319814]       =20
[  139.319817] [<ffffffff849434da>] _raw_spin_lock_irq+0x4a/0x80
[  139.320917]       =20
[  139.320919] [<ffffffff84484435>] bfq_exit_icq_bfqq+0x55/0x140
[  139.332516]       =20
[  139.332522] [<ffffffff8448453c>] bfq_exit_icq+0x1c/0x30
[  139.333551]       =20
[  139.333554] [<ffffffff844471f8>] ioc_exit_icq+0x38/0x50
[  139.334580]       =20
[  139.334582] [<ffffffff844472c9>] ioc_destroy_icq+0x99/0x140
[  139.335701]       =20
[  139.335703] [<ffffffff84447832>] ioc_clear_queue+0x52/0xa0
[  139.336758]       =20
[  139.336760] [<ffffffff8443922c>] elevator_switch+0x7c/0x240
[  139.337828]       =20
[  139.337830] [<ffffffff844394f8>] __elevator_change+0x108/0x140
[  139.338992]       =20
[  139.338996] [<ffffffff8443a4d6>] elv_iosched_store+0x26/0x60
[  139.340111]       =20
[  139.340114] [<ffffffff844447a9>] queue_attr_store+0x59/0x90
[  139.341195]       =20
[  139.341198] [<ffffffff84308585>] sysfs_kf_write+0x45/0x60
[  139.342250]       =20
[  139.342252] [<ffffffff84307815>] kernfs_fop_write+0x135/0x1c0
[  139.343354]       =20
[  139.343358] [<ffffffff8426d5a7>] __vfs_write+0x37/0x160
[  139.351596]       =20
[  139.351602] [<ffffffff8426efee>] vfs_write+0xce/0x1f0
[  139.352608]       =20
[  139.352610] [<ffffffff84270518>] SyS_write+0x58/0xc0
[  139.353615]       =20
[  139.353618] [<ffffffff84943fc5>] entry_SYSCALL_64_fastpath+0x23/0xc6
[  139.354799]=20
[  139.354799] other info that might help us debug this:
[  139.354799]=20
[  139.355925] Chain exists of:
[  139.355925]   &(&bfqd->lock)->rlock --> &(&q->__queue_lock)->rlock =
--> &(&ioc->lock)->rlock
[  139.355925]=20
[  139.357666]  Possible unsafe locking scenario:
[  139.357666]=20
[  139.368477]        CPU0                    CPU1
[  139.369129]        ----                    ----
[  139.369774]   lock(&(&ioc->lock)->rlock);
[  139.370339]                                =
lock(&(&q->__queue_lock)->rlock);
[  139.390579]                                =
lock(&(&ioc->lock)->rlock);
[  139.391522]   lock(&(&bfqd->lock)->rlock);
[  139.392094]=20
[  139.392094]  *** DEADLOCK ***
[  139.392094]=20
[  139.392912] 6 locks held by aggthr-with-gre/2170:
[  139.393562]  #0:  (sb_writers#6){.+.+.+}, at: [<ffffffff8426f0cf>] =
vfs_write+0x1af/0x1f0
[  139.396183]  #1:  (&of->mutex){+.+.+.}, at: [<ffffffff843077e1>] =
kernfs_fop_write+0x101/0x1c0
[  139.397363]  #2:  (s_active#198){.+.+.+}, at: [<ffffffff843077e9>] =
kernfs_fop_write+0x109/0x1c0
[  139.437158]  #3:  (&q->sysfs_lock){+.+.+.}, at: [<ffffffff84444792>] =
queue_attr_store+0x42/0x90
[  139.438368]  #4:  (&(&q->__queue_lock)->rlock){-.....}, at: =
[<ffffffff84439224>] elevator_switch+0x74/0x240
[  139.439741]  #5:  (&(&ioc->lock)->rlock){-.....}, at: =
[<ffffffff84447828>] ioc_clear_queue+0x48/0xa0
[  139.441008]=20
[  139.441008] stack backtrace:
[  139.441624] CPU: 0 PID: 2170 Comm: aggthr-with-gre Not tainted =
4.10.0-rc5-bfq-mq+ #42
[  139.442704] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS =
VirtualBox 12/01/2006
[  139.443918] Call Trace:
[  139.444270]  dump_stack+0x85/0xc2
[  139.444734]  print_circular_bug+0x1e3/0x250
[  139.445336]  __lock_acquire+0x15e4/0x1890
[  139.445895]  lock_acquire+0x11b/0x220
[  139.446406]  ? bfq_exit_icq_bfqq+0x55/0x140
[  139.446989]  _raw_spin_lock_irq+0x4a/0x80
[  139.451750]  ? bfq_exit_icq_bfqq+0x55/0x140
[  139.452336]  bfq_exit_icq_bfqq+0x55/0x140
[  139.452898]  bfq_exit_icq+0x1c/0x30
[  139.453386]  ioc_exit_icq+0x38/0x50
[  139.453874]  ioc_destroy_icq+0x99/0x140
[  139.454408]  ioc_clear_queue+0x52/0xa0
[  139.454930]  elevator_switch+0x7c/0x240
[  139.455489]  ? kernfs_fop_write+0x101/0x1c0
[  139.456089]  __elevator_change+0x108/0x140
[  139.456657]  elv_iosched_store+0x26/0x60
[  139.457200]  queue_attr_store+0x59/0x90
[  139.489285]  sysfs_kf_write+0x45/0x60
[  139.505169]  kernfs_fop_write+0x135/0x1c0
[  139.543726]  __vfs_write+0x37/0x160
[  139.563645]  ? rcu_read_lock_sched_held+0x72/0x80
[  139.611773]  ? rcu_sync_lockdep_assert+0x2f/0x60
[  139.651981]  ? __sb_start_write+0xde/0x1e0
[  139.683576]  ? vfs_write+0x1af/0x1f0
[  139.703898]  vfs_write+0xce/0x1f0
[  139.735970]  SyS_write+0x58/0xc0
[  139.747901]  entry_SYSCALL_64_fastpath+0x23/0xc6
[  139.748543] RIP: 0033:0x7f862b9796e0
[  139.749039] RSP: 002b:00007ffdacc878b8 EFLAGS: 00000246 ORIG_RAX: =
0000000000000001
[  139.750075] RAX: ffffffffffffffda RBX: 00007f862bc47620 RCX: =
00007f862b9796e0
[  139.761064] RDX: 0000000000000005 RSI: 0000000001560008 RDI: =
0000000000000001
[  139.811601] RBP: 0000000000000004 R08: 00007f862bc48780 R09: =
00007f862c27f700
[  139.867906] R10: 0000000000000004 R11: 0000000000000246 R12: =
0000000000000004
[  139.881848] R13: 0000000001587b28 R14: 0000000000000000 R15: =
00000000004d09d9
> Reported-by: Paolo Valente <paolo.valente@linaro.org>
> Signed-off-by: Omar Sandoval <osandov@fb.com>
> ---
> block/blk-ioc.c | 22 ++++++++++++++++------
> 1 file changed, 16 insertions(+), 6 deletions(-)
>=20
> diff --git a/block/blk-ioc.c b/block/blk-ioc.c
> index fe186a9eade9..b12f9c87b4c3 100644
> --- a/block/blk-ioc.c
> +++ b/block/blk-ioc.c
> @@ -35,7 +35,10 @@ static void icq_free_icq_rcu(struct rcu_head *head)
> 	kmem_cache_free(icq->__rcu_icq_cache, icq);
> }
>=20
> -/* Exit an icq. Called with both ioc and q locked. */
> +/*
> + * Exit an icq. Called with both ioc and q locked for sq, only ioc =
locked for
> + * mq.
> + */
> static void ioc_exit_icq(struct io_cq *icq)
> {
> 	struct elevator_type *et =3D icq->q->elevator->type;
> @@ -166,6 +169,7 @@ EXPORT_SYMBOL(put_io_context);
>  */
> void put_io_context_active(struct io_context *ioc)
> {
> +	struct elevator_type *et;
> 	unsigned long flags;
> 	struct io_cq *icq;
>=20
> @@ -184,13 +188,19 @@ void put_io_context_active(struct io_context =
*ioc)
> 	hlist_for_each_entry(icq, &ioc->icq_list, ioc_node) {
> 		if (icq->flags & ICQ_EXITED)
> 			continue;
> -		if (spin_trylock(icq->q->queue_lock)) {
> +
> +		et =3D icq->q->elevator->type;
> +		if (et->uses_mq) {
> 			ioc_exit_icq(icq);
> -			spin_unlock(icq->q->queue_lock);
> 		} else {
> -			spin_unlock_irqrestore(&ioc->lock, flags);
> -			cpu_relax();
> -			goto retry;
> +			if (spin_trylock(icq->q->queue_lock)) {
> +				ioc_exit_icq(icq);
> +				spin_unlock(icq->q->queue_lock);
> +			} else {
> +				spin_unlock_irqrestore(&ioc->lock, =
flags);
> +				cpu_relax();
> +				goto retry;
> +			}
> 		}
> 	}
> 	spin_unlock_irqrestore(&ioc->lock, flags);
> --=20
> 2.11.1
>=20

^ permalink raw reply

* Re: [PATCH v3] blk-mq-sched: separate mark hctx and queue restart operations
From: Jens Axboe @ 2017-02-15 16:54 UTC (permalink / raw)
  To: Omar Sandoval, linux-block; +Cc: kernel-team
In-Reply-To: <7b2be6bff215dcbb09b2795b08f10a87870eecfa.1487176897.git.osandov@fb.com>

On 02/15/2017 09:45 AM, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
> 
> In blk_mq_sched_dispatch_requests(), we call blk_mq_sched_mark_restart()
> after we dispatch requests left over on our hardware queue dispatch
> list. This is so we'll go back and dispatch requests from the scheduler.
> In this case, it's only necessary to restart the hardware queue that we
> are running; there's no reason to run other hardware queues just because
> we are using shared tags.
> 
> So, split out blk_mq_sched_mark_restart() into two operations, one for
> just the hardware queue and one for the whole request queue. The core
> code uses both, and I/O schedulers may also want to use them.
> 
> This also requires adjusting blk_mq_sched_restart_queues() to always
> check the queue restart flag, not just when using shared tags.

Looks good to me - just one comment:

> @@ -936,7 +936,10 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list)
>  			 * in case the needed IO completed right before we
>  			 * marked the queue as needing a restart.
>  			 */
> -			blk_mq_sched_mark_restart(hctx);
> +			if (hctx->flags & BLK_MQ_F_TAG_SHARED)
> +				blk_mq_sched_mark_restart_queue(hctx);
> +			else
> +				blk_mq_sched_mark_restart_hctx(hctx);
>  			if (!blk_mq_get_driver_tag(rq, &hctx, false))
>  				break;
>  		}

Since we now pushed the SHARED tag into the caller, I think this
warrants a comment as to why the two cases are different (getting a
driver tag can fail with 0 pending IOs for SHARED). Just update the
existing comment.

-- 
Jens Axboe

^ permalink raw reply

* [PATCH v3] blk-mq-sched: separate mark hctx and queue restart operations
From: Omar Sandoval @ 2017-02-15 16:45 UTC (permalink / raw)
  To: Jens Axboe, linux-block; +Cc: kernel-team

From: Omar Sandoval <osandov@fb.com>

In blk_mq_sched_dispatch_requests(), we call blk_mq_sched_mark_restart()
after we dispatch requests left over on our hardware queue dispatch
list. This is so we'll go back and dispatch requests from the scheduler.
In this case, it's only necessary to restart the hardware queue that we
are running; there's no reason to run other hardware queues just because
we are using shared tags.

So, split out blk_mq_sched_mark_restart() into two operations, one for
just the hardware queue and one for the whole request queue. The core
code uses both, and I/O schedulers may also want to use them.

This also requires adjusting blk_mq_sched_restart_queues() to always
check the queue restart flag, not just when using shared tags.

Signed-off-by: Omar Sandoval <osandov@fb.com>
---
Changed from v2:

- Make blk_mq_sched_restart_queues() agnostic of shared tags

 block/blk-mq-sched.c | 20 ++++++++------------
 block/blk-mq-sched.h | 26 ++++++++++++++++++--------
 block/blk-mq.c       |  5 ++++-
 3 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 97fe904f0a04..aa27ecab0d3f 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -203,7 +203,7 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
 	 * needing a restart in that case.
 	 */
 	if (!list_empty(&rq_list)) {
-		blk_mq_sched_mark_restart(hctx);
+		blk_mq_sched_mark_restart_hctx(hctx);
 		blk_mq_dispatch_rq_list(hctx, &rq_list);
 	} else if (!e || !e->type->ops.mq.dispatch_request) {
 		blk_mq_flush_busy_ctxs(hctx, &rq_list);
@@ -322,20 +322,16 @@ static void blk_mq_sched_restart_hctx(struct blk_mq_hw_ctx *hctx)
 
 void blk_mq_sched_restart_queues(struct blk_mq_hw_ctx *hctx)
 {
+	struct request_queue *q = hctx->queue;
 	unsigned int i;
 
-	if (!(hctx->flags & BLK_MQ_F_TAG_SHARED))
+	if (test_bit(QUEUE_FLAG_RESTART, &q->queue_flags)) {
+		if (test_and_clear_bit(QUEUE_FLAG_RESTART, &q->queue_flags)) {
+			queue_for_each_hw_ctx(q, hctx, i)
+				blk_mq_sched_restart_hctx(hctx);
+		}
+	} else {
 		blk_mq_sched_restart_hctx(hctx);
-	else {
-		struct request_queue *q = hctx->queue;
-
-		if (!test_bit(QUEUE_FLAG_RESTART, &q->queue_flags))
-			return;
-
-		clear_bit(QUEUE_FLAG_RESTART, &q->queue_flags);
-
-		queue_for_each_hw_ctx(q, hctx, i)
-			blk_mq_sched_restart_hctx(hctx);
 	}
 }
 
diff --git a/block/blk-mq-sched.h b/block/blk-mq-sched.h
index 7b5f3b95c78e..a75b16b123f7 100644
--- a/block/blk-mq-sched.h
+++ b/block/blk-mq-sched.h
@@ -122,17 +122,27 @@ static inline bool blk_mq_sched_has_work(struct blk_mq_hw_ctx *hctx)
 	return false;
 }
 
-static inline void blk_mq_sched_mark_restart(struct blk_mq_hw_ctx *hctx)
+/*
+ * Mark a hardware queue as needing a restart.
+ */
+static inline void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx)
 {
-	if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state)) {
+	if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
 		set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
-		if (hctx->flags & BLK_MQ_F_TAG_SHARED) {
-			struct request_queue *q = hctx->queue;
+}
+
+/*
+ * Mark a hardware queue and the request queue it belongs to as needing a
+ * restart.
+ */
+static inline void blk_mq_sched_mark_restart_queue(struct blk_mq_hw_ctx *hctx)
+{
+	struct request_queue *q = hctx->queue;
 
-			if (!test_bit(QUEUE_FLAG_RESTART, &q->queue_flags))
-				set_bit(QUEUE_FLAG_RESTART, &q->queue_flags);
-		}
-	}
+	if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
+		set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
+	if (!test_bit(QUEUE_FLAG_RESTART, &q->queue_flags))
+		set_bit(QUEUE_FLAG_RESTART, &q->queue_flags);
 }
 
 static inline bool blk_mq_sched_needs_restart(struct blk_mq_hw_ctx *hctx)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 5564a9d103ca..8fb86b9fca6c 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -936,7 +936,10 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list)
 			 * in case the needed IO completed right before we
 			 * marked the queue as needing a restart.
 			 */
-			blk_mq_sched_mark_restart(hctx);
+			if (hctx->flags & BLK_MQ_F_TAG_SHARED)
+				blk_mq_sched_mark_restart_queue(hctx);
+			else
+				blk_mq_sched_mark_restart_hctx(hctx);
 			if (!blk_mq_get_driver_tag(rq, &hctx, false))
 				break;
 		}
-- 
2.11.1

^ permalink raw reply related

* Re: [PATCH] block: do not allow updates through sysfs until registration completes
From: Jens Axboe @ 2017-02-15 15:41 UTC (permalink / raw)
  To: Tahsin Erdogan, linux-block; +Cc: linux-kernel
In-Reply-To: <20170215032738.22689-1-tahsin@google.com>

On 02/14/2017 08:27 PM, Tahsin Erdogan wrote:
> When a new disk shows up, sysfs queue directory is created before elevator
> is registered. This allows a user to attempt a scheduler switch even though
> the initial registration hasn't completed yet.
> 
> In one scenario, blk_register_queue() calls elv_register_queue() and
> right before cfq_registered_queue() is called, another process executes
> elevator_switch() and replaces q->elevator with deadline scheduler. When
> cfq_registered_queue() executes it interprets e->elevator_data as struct
> cfq_data even though it is actually struct deadline_data.
> 
> Grab q->sysfs_lock in blk_register_queue() to synchronize with sysfs
> callers.

Thanks, this looks good to me - both the grabbing of the lock, and
the ordering wrt UDEV_ADD. Queued up.

-- 
Jens Axboe

^ permalink raw reply

* Re: sense handling improvements
From: Bart Van Assche @ 2017-02-15 15:30 UTC (permalink / raw)
  To: hch@lst.de, hare@suse.de
  Cc: linux-scsi@vger.kernel.org, linux-block@vger.kernel.org,
	axboe@kernek.dk
In-Reply-To: <20170215150406.GA26549@lst.de>

T24gV2VkLCAyMDE3LTAyLTE1IGF0IDE2OjA0ICswMTAwLCBDaHJpc3RvcGggSGVsbHdpZyB3cm90
ZToNCj4gT24gV2VkLCBGZWIgMTUsIDIwMTcgYXQgMDk6MTk6MThBTSArMDEwMCwgSGFubmVzIFJl
aW5lY2tlIHdyb3RlOg0KPiA+IE9uIDAyLzE0LzIwMTcgMDg6MTUgUE0sIENocmlzdG9waCBIZWxs
d2lnIHdyb3RlOg0KPiA+ID4gSGkgYWxsLA0KPiA+ID4gDQo+ID4gPiB0aGlzIHNlcmllcyBpcyBv
biB0b3Agb2YgdGhlIHNjc2lfcmVxdWVzdCBjaGFuZ2VzIGluIEplbnMnIHRyZWUgYW5kDQo+ID4g
PiBmdXJ0aGVyIGltcHJvdmVzIHRoZSBoYW5kbGluZyBvZiB0aGUgc2Vuc2UgYnVmZmVyLg0KPiA+
ID4gDQo+ID4gDQo+ID4gU29ycnksIGJ1dCBJJ20gZmVlbGluZyByZWFsbHkgZGFmdDogd2hpY2gg
c2NzaV9yZXF1ZXN0IGNoYW5nZXM/DQo+IA0KPiBUaGF0IGlzIHRoZSAic3BsaXQgc2NzaSBwYXNz
dGhyb3VnaCBmaWVsZHMgb3V0IG9mIHN0cnVjdCByZXF1ZXN0Ig0KPiBzZXJpZXMuDQo+IA0KPiA+
IFRvIGJlIGZvdW5kIGluIHdoaWNoIHRyZWU/DQo+IA0KPiBKZW5zJyBmb3ItbmV4dCB0cmVlLCBh
cyBtZW50aW9uZWQgYWJvdmUuDQoNCkhlbGxvIENocmlzdG9waCwNCg0KQXJlIHlvdSBhd2FyZSB0
aGF0ICJzcGxpdCBzY3NpIHBhc3N0aHJvdWdoIGZpZWxkcyBvdXQgb2Ygc3RydWN0IHJlcXVlc3Qi
DQpzZXJpZXMgaW50cm9kdWNlcyBhIG5ldyBidWcsIGEgYnVnIHRoYXQgSSBoYXZlIGFscmVhZHkg
cmVwb3J0ZWQgYnV0IHRoYXQNCmhhcyBub3QgeWV0IGJlZW4gYWRkcmVzc2VkPyBTZWUgYWxzbw0K
aHR0cHM6Ly93d3cuc3Bpbmljcy5uZXQvbGlzdHMvcmFpZC9tc2c1NTQ5NC5odG1sLg0KDQpCYXJ0
Lg==

^ permalink raw reply

* Re: [PATCH 0/2] Small fixes for LightNVM core
From: Jens Axboe @ 2017-02-15 15:27 UTC (permalink / raw)
  To: Matias Bjørling; +Cc: linux-block, linux-kernel
In-Reply-To: <20170215152533.9712-1-matias@cnexlabs.com>

On 02/15/2017 08:25 AM, Matias Bjørling wrote:
> Hi Jens,
> 
> Would these two small patches be able to make it for the 4.11 window? If
> not it is totally fine, and I'll include them in the 4.12 drop.

There's still time, queued up for 4.11.

-- 
Jens Axboe

^ permalink raw reply

* Re: sense handling improvements
From: Christoph Hellwig @ 2017-02-15 15:04 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: Christoph Hellwig, axboe, linux-block, linux-scsi
In-Reply-To: <cfc712df-f0e6-59c0-46d8-6af02542f14b@suse.de>

On Wed, Feb 15, 2017 at 09:19:18AM +0100, Hannes Reinecke wrote:
> On 02/14/2017 08:15 PM, Christoph Hellwig wrote:
> > Hi all,
> > 
> > this series is on top of the scsi_request changes in Jens' tree and
> > further improves the handling of the sense buffer.
> > 
> Sorry, but I'm feeling really daft: which scsi_request changes?

That is the "split scsi passthrough fields out of struct request"
series.

> To be found in which tree?

Jens' for-next tree, as mentioned above.

> Have we audited all drivers to _not_ do DMA into the sense buffer?
> By first glance some still do, so they'll break horribly when moving the
> sense buffer onto the stack ...

With the above series the sense buffer is allocate by the driver,
and they will always DMA into that.

^ permalink raw reply

* RE: Boot regression (was "Re: [PATCH] genhd: Do not hold event lock when scheduling workqueue elements")
From: Dexuan Cui @ 2017-02-15 13:51 UTC (permalink / raw)
  To: hch@lst.de
  Cc: Jens Axboe, Bart Van Assche, hare@suse.com, hare@suse.de,
	Martin K. Petersen, linux-kernel@vger.kernel.org,
	linux-block@vger.kernel.org, jth@kernel.org, Nick Meier,
	Alex Ng (LIS), Long Li, Adrian Suhov (Cloudbase Solutions SRL),
	Chris Valean (Cloudbase Solutions SRL)
In-Reply-To: <20170214163437.GA23956@lst.de>

> From: hch@lst.de [mailto:hch@lst.de]
> Sent: Wednesday, February 15, 2017 00:35
> > I tested today's linux-next (next-20170214) + the 2 patches just now an=
d
> got
> > a weird result:
> > sometimes the VM stills hung with a new calltrace (BUG: spinlock bad
> > magic) , but sometimes the VM did boot up despite the new calltrace!
> >
> > Attached is the log of a "good" boot.
> >
> > It looks we have a memory corruption issue somewhere...
>
> Yes.
It's due to an uninitialized spinlock. Please see the below.

> > Actually previously I saw the "BUG: spinlock bad magic" message once, b=
ut
> I
> > couldn't repro it later, so I didn't mention it to you.
>
> Interesting.
Ditto.
And probably my memory was inaccurate due to the long period of bisecting.
We should always see the message.

>
> A few questions on the dmesg:
>
> [    6.208794] sd 2:0:0:0: [storvsc] Sense Key : Illegal Request [current=
]
> [    6.209447] sd 2:0:0:0: [storvsc] Add. Sense: Invalid command operatio=
n
> code
> [    6.210043] sd 3:0:0:0: [storvsc] Sense Key : Illegal Request [current=
]
> [    6.210618] sd 3:0:0:0: [storvsc] Add. Sense: Invalid command operatio=
n
> code
> [    6.212272] sd 2:0:0:0: [storvsc] Sense Key : Illegal Request [current=
]
> [    6.212897] sd 2:0:0:0: [storvsc] Add. Sense: Invalid command operatio=
n
> code
> [    6.213474] sd 3:0:0:0: [storvsc] Sense Key : Illegal Request [current=
]
> [    6.214051] sd 3:0:0:0: [storvsc] Add. Sense: Invalid command operatio=
n
> code
>
> I didn't see anything like this in the other logs.  Are these messages
> something usual on HyperV VMs?

The messages should be normal, and I have always seen them for years
at least.

I think they're triggered by "/sbin/hdparm /dev/sda" or
"/lib/udev/ata_id /dev/sda"  in my Ubuntu 16.04 VM: during the VM
boot-up, the 2 programs are executed by the initrd's systemd-udev or other
system init scripts and the 2 programs try to run these 2 SCSI commands,
which are not supported by Hyper-V:

ATA PASS THROUGH (12) -- 0xa1
ATA PASS THROUGH (16) -- 0x85

IMO the commands are used when PATA/SATA devices are connected to
SCSI-to-ATA bridge, so it's understandable that Hyper-V doesn't support
them.

In the case of boot failure (hang), the 2 programs don't have a chance to
run, so we can't see the messages.

IMO we should ignore the messages, which should be harmless.

> [    6.358405] XFS (sdb1): Mounting V5 Filesystem
> [    6.404478] XFS (sdb1): Ending clean mount
> [    7.535174] BUG: spinlock bad magic on CPU#0, swapper/0/0
> [    7.536807]  lock: host_ts+0x30/0xffffffffffffe1a0 [hv_utils], .magic:
> 00000000, .owner: <none>/-1, .owner_cpu: 0
> [    7.538436] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.10.0-rc8-next-
> 20170214+ #1
> [    7.539142] Hardware name: Microsoft Corporation Virtual Machine/Virtu=
al
> Machine, BIOS 090006  04/28/2016
> [    7.539142] Call Trace:
> [    7.539142]  <IRQ>
> [    7.539142]  dump_stack+0x63/0x82
> [    7.539142]  spin_dump+0x78/0xc0
> [    7.539142]  do_raw_spin_lock+0xfd/0x160
> [    7.539142]  _raw_spin_lock_irqsave+0x4c/0x60
> [    7.539142]  ? timesync_onchannelcallback+0x153/0x220 [hv_utils]
> [    7.539142]  timesync_onchannelcallback+0x153/0x220 [hv_utils]
>
> Can you resolve this address using gdb to a line of code?  Once inside
> gdb do:
>
> l *(timesync_onchannelcallback+0x153)

(gdb) l *(timesync_onchannelcallback+0x153)
0xffffffffc0104593 is in timesync_onchannelcallback (drivers/hv/hv_util.c:2=
79).
274             } else {
275                     /*
276                      * Save the adjusted time sample from the host and =
the snapshot
277                      * of the current system time for PTP device.
278                      */
279                     spin_lock_irqsave(&host_ts.lock, flags);
280
281                     cur_reftime =3D hyperv_cs->read(hyperv_cs);
282                     host_ts.host_time =3D hosttime;
283                     host_ts.ref_time =3D cur_reftime;

It turns out the "host_ts.lock" isn't initialized with spin_lock_init().
I'll submit a patch for this.

However, the SCSI issue (i.e. *sometimes* the VM fails to boot) is still th=
ere, I think.
We need to continue to debug...

Thanks,
-- Dexuan

^ permalink raw reply

* Re: [PATCH] mmc: core: make block layer non-optional
From: kbuild test robot @ 2017-02-15 12:19 UTC (permalink / raw)
  To: Linus Walleij
  Cc: kbuild-all, linux-mmc, Ulf Hansson, Adrian Hunter, Paolo Valente,
	linux-block, Jens Axboe, Christoph Hellwig, Arnd Bergmann,
	Linus Walleij
In-Reply-To: <20170215095353.23888-1-linus.walleij@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 22905 bytes --]

Hi Linus,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.10-rc8 next-20170215]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Linus-Walleij/mmc-core-make-block-layer-non-optional/20170215-181952
config: i386-randconfig-h1-02151737 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from drivers/mmc/core/block.c:48:0:
   drivers/mmc/core/queue.h: In function 'mmc_req_is_special':
   drivers/mmc/core/queue.h:7:4: error: implicit declaration of function 'req_op' [-Werror=implicit-function-declaration]
      (req_op(req) == REQ_OP_FLUSH ||
       ^~~~~~
   drivers/mmc/core/queue.h:7:19: error: 'REQ_OP_FLUSH' undeclared (first use in this function)
      (req_op(req) == REQ_OP_FLUSH ||
                      ^~~~~~~~~~~~
   drivers/mmc/core/queue.h:7:19: note: each undeclared identifier is reported only once for each function it appears in
   drivers/mmc/core/queue.h:8:19: error: 'REQ_OP_DISCARD' undeclared (first use in this function)
       req_op(req) == REQ_OP_DISCARD ||
                      ^~~~~~~~~~~~~~
   drivers/mmc/core/queue.h:9:19: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function)
       req_op(req) == REQ_OP_SECURE_ERASE);
                      ^~~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_get':
>> drivers/mmc/core/block.c:137:11: error: dereferencing pointer to incomplete type 'struct gendisk'
     md = disk->private_data;
              ^~
   drivers/mmc/core/block.c: In function 'mmc_blk_put':
   drivers/mmc/core/block.c:159:3: error: implicit declaration of function 'blk_cleanup_queue' [-Werror=implicit-function-declaration]
      blk_cleanup_queue(md->queue.queue);
      ^~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:165:3: error: implicit declaration of function 'put_disk' [-Werror=implicit-function-declaration]
      put_disk(md->disk);
      ^~~~~~~~
   drivers/mmc/core/block.c: In function 'power_ro_lock_show':
   drivers/mmc/core/block.c:175:40: error: implicit declaration of function 'dev_to_disk' [-Werror=implicit-function-declaration]
     struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
                                           ^~~~~~~~~~~
   drivers/mmc/core/block.c:175:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion]
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'power_ro_lock_store':
   drivers/mmc/core/block.c:205:19: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion]
     md = mmc_blk_get(dev_to_disk(dev));
                      ^~~~~~~~~~~
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^~~~~~~~~~~
   drivers/mmc/core/block.c:224:3: error: implicit declaration of function 'set_disk_ro' [-Werror=implicit-function-declaration]
      set_disk_ro(md->disk, 1);
      ^~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'force_ro_show':
   drivers/mmc/core/block.c:241:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion]
     struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
                                           ^~~~~~~~~~~
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^~~~~~~~~~~
   drivers/mmc/core/block.c:244:10: error: implicit declaration of function 'get_disk_ro' [-Werror=implicit-function-declaration]
             get_disk_ro(dev_to_disk(dev)) ^
             ^~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'force_ro_store':
   drivers/mmc/core/block.c:255:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast [-Wint-conversion]
     struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
                                           ^~~~~~~~~~~
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_open':
   drivers/mmc/core/block.c:277:4: error: implicit declaration of function 'check_disk_change' [-Werror=implicit-function-declaration]
       check_disk_change(bdev);
       ^~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_getgeo':
   drivers/mmc/core/block.c:302:19: error: implicit declaration of function 'get_capacity' [-Werror=implicit-function-declaration]
     geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
                      ^~~~~~~~~~~~
   In file included from include/asm-generic/ioctl.h:4:0,
                    from arch/x86/include/uapi/asm/ioctl.h:1,
                    from include/uapi/linux/ioctl.h:4,
                    from arch/x86/include/uapi/asm/msr.h:7,
                    from arch/x86/include/asm/msr.h:11,
                    from arch/x86/include/asm/processor.h:20,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/seqlock.h:35,
                    from include/linux/time.h:5,
                    from include/linux/stat.h:18,
                    from include/linux/module.h:10,
                    from drivers/mmc/core/block.c:21:
   drivers/mmc/core/block.c: In function 'mmc_blk_ioctl':
   include/uapi/linux/mmc/ioctl.h:59:27: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function)
    #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
                              ^
   include/uapi/asm-generic/ioctl.h:67:5: note: in definition of macro '_IOC'
      ((type) << _IOC_TYPESHIFT) | \
        ^~~~
   include/uapi/linux/mmc/ioctl.h:59:21: note: in expansion of macro '_IOWR'
    #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
                        ^~~~~
   drivers/mmc/core/block.c:698:7: note: in expansion of macro 'MMC_IOC_CMD'
     case MMC_IOC_CMD:
          ^~~~~~~~~~~
   drivers/mmc/core/block.c: At top level:
   drivers/mmc/core/block.c:717:21: error: variable 'mmc_bdops' has initializer but incomplete type
    static const struct block_device_operations mmc_bdops = {
                        ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:718:2: error: unknown field 'open' specified in initializer
     .open   = mmc_blk_open,
     ^
   drivers/mmc/core/block.c:718:12: warning: excess elements in struct initializer
     .open   = mmc_blk_open,
               ^~~~~~~~~~~~
   drivers/mmc/core/block.c:718:12: note: (near initialization for 'mmc_bdops')
   drivers/mmc/core/block.c:719:2: error: unknown field 'release' specified in initializer
     .release  = mmc_blk_release,
     ^
   drivers/mmc/core/block.c:719:14: warning: excess elements in struct initializer
     .release  = mmc_blk_release,
                 ^~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:719:14: note: (near initialization for 'mmc_bdops')
   drivers/mmc/core/block.c:720:2: error: unknown field 'getgeo' specified in initializer
     .getgeo   = mmc_blk_getgeo,
     ^
   drivers/mmc/core/block.c:720:14: warning: excess elements in struct initializer
     .getgeo   = mmc_blk_getgeo,
                 ^~~~~~~~~~~~~~
   drivers/mmc/core/block.c:720:14: note: (near initialization for 'mmc_bdops')
   drivers/mmc/core/block.c:721:2: error: unknown field 'owner' specified in initializer
     .owner   = THIS_MODULE,
     ^
   In file included from include/linux/linkage.h:6:0,
                    from include/linux/kernel.h:6,
                    from include/linux/moduleparam.h:6,
                    from drivers/mmc/core/block.c:20:
   include/linux/export.h:37:21: warning: excess elements in struct initializer
    #define THIS_MODULE ((struct module *)0)
                        ^
   drivers/mmc/core/block.c:721:13: note: in expansion of macro 'THIS_MODULE'
     .owner   = THIS_MODULE,
                ^~~~~~~~~~~
   include/linux/export.h:37:21: note: (near initialization for 'mmc_bdops')
    #define THIS_MODULE ((struct module *)0)
                        ^
   drivers/mmc/core/block.c:721:13: note: in expansion of macro 'THIS_MODULE'
     .owner   = THIS_MODULE,
                ^~~~~~~~~~~
   drivers/mmc/core/block.c:722:2: error: unknown field 'ioctl' specified in initializer
     .ioctl   = mmc_blk_ioctl,
     ^
   drivers/mmc/core/block.c:722:13: warning: excess elements in struct initializer
     .ioctl   = mmc_blk_ioctl,
                ^~~~~~~~~~~~~
   drivers/mmc/core/block.c:722:13: note: (near initialization for 'mmc_bdops')
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/moduleparam.h:6,
                    from drivers/mmc/core/block.c:20:
   drivers/mmc/core/block.c: In function 'card_busy_detect':
>> drivers/mmc/core/block.c:846:14: error: dereferencing pointer to incomplete type 'struct request'
              req->rq_disk->disk_name, err);
                 ^
   include/linux/printk.h:292:33: note: in definition of macro 'pr_err'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                                    ^~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'send_stop':
   drivers/mmc/core/block.c:889:22: error: implicit declaration of function 'rq_data_dir' [-Werror=implicit-function-declaration]
     bool use_r1b_resp = rq_data_dir(req) == WRITE;
                         ^~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_issue_discard_rq':
   drivers/mmc/core/block.c:1158:9: error: implicit declaration of function 'blk_rq_pos' [-Werror=implicit-function-declaration]
     from = blk_rq_pos(req);
            ^~~~~~~~~~
   drivers/mmc/core/block.c:1159:7: error: implicit declaration of function 'blk_rq_sectors' [-Werror=implicit-function-declaration]
     nr = blk_rq_sectors(req);
          ^~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1184:2: error: implicit declaration of function 'blk_end_request' [-Werror=implicit-function-declaration]
     blk_end_request(req, err, blk_rq_bytes(req));
     ^~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1184:28: error: implicit declaration of function 'blk_rq_bytes' [-Werror=implicit-function-declaration]
     blk_end_request(req, err, blk_rq_bytes(req));
                               ^~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_issue_flush':
   drivers/mmc/core/block.c:1266:2: error: implicit declaration of function 'blk_end_request_all' [-Werror=implicit-function-declaration]
     blk_end_request_all(req, ret);
     ^~~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_rw_rq_prep':
   drivers/mmc/core/block.c:1423:37: error: 'REQ_FUA' undeclared (first use in this function)
     bool do_rel_wr = (req->cmd_flags & REQ_FUA) &&
                                        ^~~~~~~
   drivers/mmc/core/block.c:1504:21: error: 'REQ_META' undeclared (first use in this function)
      (req->cmd_flags & REQ_META) &&
                        ^~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_issue_rw_rq':
   drivers/mmc/core/block.c:1736:20: error: 'RQF_QUIET' undeclared (first use in this function)
      req->rq_flags |= RQF_QUIET;
                       ^~~~~~~~~
   drivers/mmc/core/block.c:1739:5: error: implicit declaration of function 'blk_rq_cur_bytes' [-Werror=implicit-function-declaration]
        blk_rq_cur_bytes(req));
        ^~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_issue_rq':
   drivers/mmc/core/block.c:1777:28: error: 'REQ_OP_DISCARD' undeclared (first use in this function)
     if (req && req_op(req) == REQ_OP_DISCARD) {
                               ^~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1782:35: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function)
     } else if (req && req_op(req) == REQ_OP_SECURE_ERASE) {
                                      ^~~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1787:35: error: 'REQ_OP_FLUSH' undeclared (first use in this function)
     } else if (req && req_op(req) == REQ_OP_FLUSH) {
                                      ^~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_alloc_req':
   drivers/mmc/core/block.c:1856:13: error: implicit declaration of function 'alloc_disk' [-Werror=implicit-function-declaration]
     md->disk = alloc_disk(perdev_minors);
                ^~~~~~~~~~
   drivers/mmc/core/block.c:1856:11: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     md->disk = alloc_disk(perdev_minors);
              ^
   drivers/mmc/core/block.c:1872:20: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function)
     md->disk->major = MMC_BLOCK_MAJOR;
                       ^~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1879:20: error: 'GENHD_FL_EXT_DEVT' undeclared (first use in this function)
     md->disk->flags = GENHD_FL_EXT_DEVT;
                       ^~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1881:22: error: 'GENHD_FL_NO_PART_SCAN' undeclared (first use in this function)
      md->disk->flags |= GENHD_FL_NO_PART_SCAN;
                         ^~~~~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1899:3: error: implicit declaration of function 'blk_queue_logical_block_size' [-Werror=implicit-function-declaration]
      blk_queue_logical_block_size(md->queue.queue,
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:1904:2: error: implicit declaration of function 'set_capacity' [-Werror=implicit-function-declaration]
     set_capacity(md->disk, size);
     ^~~~~~~~~~~~
   drivers/mmc/core/block.c:1919:3: error: implicit declaration of function 'blk_queue_write_cache' [-Werror=implicit-function-declaration]
      blk_queue_write_cache(md->queue.queue, true, true);
      ^~~~~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_alloc_part':
   drivers/mmc/core/block.c:1969:36: error: implicit declaration of function 'disk_to_dev' [-Werror=implicit-function-declaration]
     part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro,
                                       ^~~~~~~~~~~
   drivers/mmc/core/block.c:1969:36: warning: passing argument 2 of 'mmc_blk_alloc_req' makes pointer from integer without a cast [-Wint-conversion]
   drivers/mmc/core/block.c:1814:29: note: expected 'struct device *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
                                ^~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_remove_req':
   drivers/mmc/core/block.c:2025:25: error: 'GENHD_FL_UP' undeclared (first use in this function)
      if (md->disk->flags & GENHD_FL_UP) {
                            ^~~~~~~~~~~
   drivers/mmc/core/block.c:2026:23: warning: passing argument 1 of 'device_remove_file' makes pointer from integer without a cast [-Wint-conversion]
       device_remove_file(disk_to_dev(md->disk), &md->force_ro);
                          ^~~~~~~~~~~
   In file included from include/linux/pm_runtime.h:12:0,
                    from drivers/mmc/core/block.c:37:
   include/linux/device.h:602:13: note: expected 'struct device *' but argument is of type 'int'
    extern void device_remove_file(struct device *dev,
                ^~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:2029:24: warning: passing argument 1 of 'device_remove_file' makes pointer from integer without a cast [-Wint-conversion]
        device_remove_file(disk_to_dev(md->disk),
                           ^~~~~~~~~~~
   In file included from include/linux/pm_runtime.h:12:0,
                    from drivers/mmc/core/block.c:37:
   include/linux/device.h:602:13: note: expected 'struct device *' but argument is of type 'int'
    extern void device_remove_file(struct device *dev,
                ^~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:2032:4: error: implicit declaration of function 'del_gendisk' [-Werror=implicit-function-declaration]
       del_gendisk(md->disk);
       ^~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_add_disk':
   drivers/mmc/core/block.c:2056:2: error: implicit declaration of function 'device_add_disk' [-Werror=implicit-function-declaration]
     device_add_disk(md->parent, md->disk);
     ^~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:2062:27: warning: passing argument 1 of 'device_create_file' makes pointer from integer without a cast [-Wint-conversion]
     ret = device_create_file(disk_to_dev(md->disk), &md->force_ro);
                              ^~~~~~~~~~~
   In file included from include/linux/pm_runtime.h:12:0,
                    from drivers/mmc/core/block.c:37:
   include/linux/device.h:600:12: note: expected 'struct device *' but argument is of type 'int'
    extern int device_create_file(struct device *device,
               ^~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:2081:28: warning: passing argument 1 of 'device_create_file' makes pointer from integer without a cast [-Wint-conversion]
      ret = device_create_file(disk_to_dev(md->disk),
                               ^~~~~~~~~~~
   In file included from include/linux/pm_runtime.h:12:0,
                    from drivers/mmc/core/block.c:37:
   include/linux/device.h:600:12: note: expected 'struct device *' but argument is of type 'int'
    extern int device_create_file(struct device *device,
               ^~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:2089:21: warning: passing argument 1 of 'device_remove_file' makes pointer from integer without a cast [-Wint-conversion]
     device_remove_file(disk_to_dev(md->disk), &md->force_ro);
                        ^~~~~~~~~~~
   In file included from include/linux/pm_runtime.h:12:0,
                    from drivers/mmc/core/block.c:37:
   include/linux/device.h:602:13: note: expected 'struct device *' but argument is of type 'int'
    extern void device_remove_file(struct device *dev,
                ^~~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_init':
   drivers/mmc/core/block.c:2310:8: error: implicit declaration of function 'register_blkdev' [-Werror=implicit-function-declaration]
     res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
           ^~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:2310:24: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function)
     res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
                           ^~~~~~~~~~~~~~~
   drivers/mmc/core/block.c:2320:2: error: implicit declaration of function 'unregister_blkdev' [-Werror=implicit-function-declaration]
     unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
     ^~~~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: In function 'mmc_blk_exit':
   drivers/mmc/core/block.c:2328:20: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function)
     unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
                       ^~~~~~~~~~~~~~~
   drivers/mmc/core/block.c: At top level:
>> drivers/mmc/core/block.c:717:45: error: storage size of 'mmc_bdops' isn't known
    static const struct block_device_operations mmc_bdops = {
                                                ^~~~~~~~~
   In file included from drivers/mmc/core/block.c:48:0:
   drivers/mmc/core/queue.h: In function 'mmc_req_is_special':
   drivers/mmc/core/queue.h:10:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^
   cc1: some warnings being treated as errors
..

vim +137 drivers/mmc/core/block.c

^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  121  };
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  122  
a621aaed drivers/mmc/mmc_block.c  Arjan van de Ven 2006-01-12  123  static DEFINE_MUTEX(open_lock);
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  124  
5e71b7a6 drivers/mmc/card/block.c Olof Johansson   2010-09-17  125  module_param(perdev_minors, int, 0444);
5e71b7a6 drivers/mmc/card/block.c Olof Johansson   2010-09-17  126  MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
5e71b7a6 drivers/mmc/card/block.c Olof Johansson   2010-09-17  127  
8d1e977d drivers/mmc/card/block.c Loic Pallardy    2012-08-06  128  static inline int mmc_blk_part_switch(struct mmc_card *card,
8d1e977d drivers/mmc/card/block.c Loic Pallardy    2012-08-06  129  				      struct mmc_blk_data *md);
8d1e977d drivers/mmc/card/block.c Loic Pallardy    2012-08-06  130  static int get_card_status(struct mmc_card *card, u32 *status, int retries);
8d1e977d drivers/mmc/card/block.c Loic Pallardy    2012-08-06  131  
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  132  static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  133  {
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  134  	struct mmc_blk_data *md;
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  135  
a621aaed drivers/mmc/mmc_block.c  Arjan van de Ven 2006-01-12  136  	mutex_lock(&open_lock);
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16 @137  	md = disk->private_data;
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  138  	if (md && md->usage == 0)
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  139  		md = NULL;
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  140  	if (md)
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  141  		md->usage++;
a621aaed drivers/mmc/mmc_block.c  Arjan van de Ven 2006-01-12  142  	mutex_unlock(&open_lock);
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  143  
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  144  	return md;
^1da177e drivers/mmc/mmc_block.c  Linus Torvalds   2005-04-16  145  }

:::::: The code at line 137 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23601 bytes --]

^ permalink raw reply

* Re: [PATCH] mmc: core: make block layer non-optional
From: kbuild test robot @ 2017-02-15 12:03 UTC (permalink / raw)
  To: Linus Walleij
  Cc: kbuild-all, linux-mmc, Ulf Hansson, Adrian Hunter, Paolo Valente,
	linux-block, Jens Axboe, Christoph Hellwig, Arnd Bergmann,
	Linus Walleij
In-Reply-To: <20170215095353.23888-1-linus.walleij@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 18530 bytes --]

Hi Linus,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.10-rc8 next-20170215]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Linus-Walleij/mmc-core-make-block-layer-non-optional/20170215-181952
config: i386-randconfig-c0-02151724 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   In file included from drivers/mmc/core/block.c:48:0:
   drivers/mmc/core/queue.h: In function 'mmc_req_is_special':
>> drivers/mmc/core/queue.h:7:3: error: implicit declaration of function 'req_op' [-Werror=implicit-function-declaration]
      (req_op(req) == REQ_OP_FLUSH ||
      ^
>> drivers/mmc/core/queue.h:7:19: error: 'REQ_OP_FLUSH' undeclared (first use in this function)
      (req_op(req) == REQ_OP_FLUSH ||
                      ^
   drivers/mmc/core/queue.h:7:19: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/mmc/core/queue.h:8:19: error: 'REQ_OP_DISCARD' undeclared (first use in this function)
       req_op(req) == REQ_OP_DISCARD ||
                      ^
>> drivers/mmc/core/queue.h:9:19: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function)
       req_op(req) == REQ_OP_SECURE_ERASE);
                      ^
   drivers/mmc/core/block.c: In function 'mmc_blk_get':
>> drivers/mmc/core/block.c:137:11: error: dereferencing pointer to incomplete type
     md = disk->private_data;
              ^
   drivers/mmc/core/block.c: In function 'mmc_get_devidx':
   drivers/mmc/core/block.c:149:19: error: dereferencing pointer to incomplete type
     int devidx = disk->first_minor / perdev_minors;
                      ^
   drivers/mmc/core/block.c: In function 'mmc_blk_put':
>> drivers/mmc/core/block.c:159:3: error: implicit declaration of function 'blk_cleanup_queue' [-Werror=implicit-function-declaration]
      blk_cleanup_queue(md->queue.queue);
      ^
>> drivers/mmc/core/block.c:165:3: error: implicit declaration of function 'put_disk' [-Werror=implicit-function-declaration]
      put_disk(md->disk);
      ^
   drivers/mmc/core/block.c: In function 'power_ro_lock_show':
>> drivers/mmc/core/block.c:175:9: error: implicit declaration of function 'dev_to_disk' [-Werror=implicit-function-declaration]
     struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
            ^
>> drivers/mmc/core/block.c:175:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast
     struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
                                           ^
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^
   drivers/mmc/core/block.c: In function 'power_ro_lock_store':
   drivers/mmc/core/block.c:205:19: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast
     md = mmc_blk_get(dev_to_disk(dev));
                      ^
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/moduleparam.h:6,
                    from drivers/mmc/core/block.c:20:
   drivers/mmc/core/block.c:215:84: error: dereferencing pointer to incomplete type
      pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret);
                                                                                       ^
   include/linux/printk.h:292:33: note: in definition of macro 'pr_err'
     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
                                    ^
   drivers/mmc/core/block.c:223:12: error: dereferencing pointer to incomplete type
       md->disk->disk_name);
               ^
   include/linux/printk.h:299:34: note: in definition of macro 'pr_info'
     printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
                                     ^
>> drivers/mmc/core/block.c:224:3: error: implicit declaration of function 'set_disk_ro' [-Werror=implicit-function-declaration]
      set_disk_ro(md->disk, 1);
      ^
   In file included from include/linux/kernel.h:13:0,
                    from include/linux/moduleparam.h:6,
                    from drivers/mmc/core/block.c:20:
   drivers/mmc/core/block.c:228:81: error: dereferencing pointer to incomplete type
        pr_info("%s: Locking boot partition ro until next power on\n", part_md->disk->disk_name);
                                                                                    ^
   include/linux/printk.h:299:34: note: in definition of macro 'pr_info'
     printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
                                     ^
   drivers/mmc/core/block.c: In function 'force_ro_show':
   drivers/mmc/core/block.c:241:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast
     struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
                                           ^
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^
>> drivers/mmc/core/block.c:244:10: error: implicit declaration of function 'get_disk_ro' [-Werror=implicit-function-declaration]
             get_disk_ro(dev_to_disk(dev)) ^
             ^
   drivers/mmc/core/block.c: In function 'force_ro_store':
   drivers/mmc/core/block.c:255:40: warning: passing argument 1 of 'mmc_blk_get' makes pointer from integer without a cast
     struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
                                           ^
   drivers/mmc/core/block.c:132:29: note: expected 'struct gendisk *' but argument is of type 'int'
    static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
                                ^
   drivers/mmc/core/block.c: In function 'mmc_blk_open':
>> drivers/mmc/core/block.c:277:4: error: implicit declaration of function 'check_disk_change' [-Werror=implicit-function-declaration]
       check_disk_change(bdev);
       ^
   drivers/mmc/core/block.c: In function 'mmc_blk_release':
   drivers/mmc/core/block.c:292:32: error: dereferencing pointer to incomplete type
     struct mmc_blk_data *md = disk->private_data;
                                   ^
   drivers/mmc/core/block.c: In function 'mmc_blk_getgeo':
>> drivers/mmc/core/block.c:302:2: error: implicit declaration of function 'get_capacity' [-Werror=implicit-function-declaration]
     geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
     ^
   In file included from include/asm-generic/ioctl.h:4:0,
                    from arch/x86/include/uapi/asm/ioctl.h:1,
                    from include/uapi/linux/ioctl.h:4,
                    from arch/x86/include/uapi/asm/msr.h:7,
                    from arch/x86/include/asm/msr.h:11,
                    from arch/x86/include/asm/processor.h:20,
                    from arch/x86/include/asm/cpufeature.h:4,
                    from arch/x86/include/asm/thread_info.h:52,
                    from include/linux/thread_info.h:25,
                    from arch/x86/include/asm/preempt.h:6,
                    from include/linux/preempt.h:59,
                    from include/linux/spinlock.h:50,
                    from include/linux/seqlock.h:35,
                    from include/linux/time.h:5,
                    from include/linux/stat.h:18,
                    from include/linux/module.h:10,
                    from drivers/mmc/core/block.c:21:
   drivers/mmc/core/block.c: In function 'mmc_blk_ioctl':
>> include/uapi/linux/mmc/ioctl.h:59:27: error: 'MMC_BLOCK_MAJOR' undeclared (first use in this function)
    #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
                              ^
   include/uapi/asm-generic/ioctl.h:67:5: note: in definition of macro '_IOC'
      ((type) << _IOC_TYPESHIFT) | \
        ^
>> include/uapi/linux/mmc/ioctl.h:59:21: note: in expansion of macro '_IOWR'
    #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
                        ^
>> drivers/mmc/core/block.c:698:7: note: in expansion of macro 'MMC_IOC_CMD'
     case MMC_IOC_CMD:
          ^
   drivers/mmc/core/block.c: At top level:
>> drivers/mmc/core/block.c:717:21: error: variable 'mmc_bdops' has initializer but incomplete type
    static const struct block_device_operations mmc_bdops = {
                        ^
>> drivers/mmc/core/block.c:718:2: error: unknown field 'open' specified in initializer
     .open   = mmc_blk_open,
     ^
>> drivers/mmc/core/block.c:718:2: warning: excess elements in struct initializer
   drivers/mmc/core/block.c:718:2: warning: (near initialization for 'mmc_bdops')
>> drivers/mmc/core/block.c:719:2: error: unknown field 'release' specified in initializer
     .release  = mmc_blk_release,
     ^
   drivers/mmc/core/block.c:719:2: warning: excess elements in struct initializer
   drivers/mmc/core/block.c:719:2: warning: (near initialization for 'mmc_bdops')
--
   In file included from drivers/mmc/core/queue.c:21:0:
   drivers/mmc/core/queue.h: In function 'mmc_req_is_special':
>> drivers/mmc/core/queue.h:7:3: error: implicit declaration of function 'req_op' [-Werror=implicit-function-declaration]
      (req_op(req) == REQ_OP_FLUSH ||
      ^
>> drivers/mmc/core/queue.h:7:19: error: 'REQ_OP_FLUSH' undeclared (first use in this function)
      (req_op(req) == REQ_OP_FLUSH ||
                      ^
   drivers/mmc/core/queue.h:7:19: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/mmc/core/queue.h:8:19: error: 'REQ_OP_DISCARD' undeclared (first use in this function)
       req_op(req) == REQ_OP_DISCARD ||
                      ^
>> drivers/mmc/core/queue.h:9:19: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function)
       req_op(req) == REQ_OP_SECURE_ERASE);
                      ^
   drivers/mmc/core/queue.h: At top level:
>> drivers/mmc/core/queue.h:38:19: error: field 'thread_sem' has incomplete type
     struct semaphore thread_sem;
                      ^
   drivers/mmc/core/queue.c: In function 'mmc_prep_request':
>> drivers/mmc/core/queue.c:31:26: error: dereferencing pointer to incomplete type
     struct mmc_queue *mq = q->queuedata;
                             ^
   drivers/mmc/core/queue.c:36:9: error: dereferencing pointer to incomplete type
     if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD &&
            ^
>> drivers/mmc/core/queue.c:36:23: error: 'REQ_TYPE_FS' undeclared (first use in this function)
     if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD &&
                          ^
>> drivers/mmc/core/queue.c:36:53: error: 'REQ_OP_DISCARD' undeclared (first use in this function)
     if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD &&
                                                        ^
>> drivers/mmc/core/queue.c:37:21: error: 'REQ_OP_SECURE_ERASE' undeclared (first use in this function)
         req_op(req) != REQ_OP_SECURE_ERASE) {
                        ^
>> drivers/mmc/core/queue.c:38:3: error: implicit declaration of function 'blk_dump_rq_flags' [-Werror=implicit-function-declaration]
      blk_dump_rq_flags(req, "MMC bad request");
      ^
>> drivers/mmc/core/queue.c:39:10: error: 'BLKPREP_KILL' undeclared (first use in this function)
      return BLKPREP_KILL;
             ^
   drivers/mmc/core/queue.c:45:5: error: dereferencing pointer to incomplete type
     req->rq_flags |= RQF_DONTPREP;
        ^
>> drivers/mmc/core/queue.c:45:19: error: 'RQF_DONTPREP' undeclared (first use in this function)
     req->rq_flags |= RQF_DONTPREP;
                      ^
>> drivers/mmc/core/queue.c:47:9: error: 'BLKPREP_OK' undeclared (first use in this function)
     return BLKPREP_OK;
            ^
   drivers/mmc/core/queue.c: In function 'mmc_queue_thread':
>> drivers/mmc/core/queue.c:58:2: error: implicit declaration of function 'down' [-Werror=implicit-function-declaration]
     down(&mq->thread_sem);
     ^
   drivers/mmc/core/queue.c:62:18: error: dereferencing pointer to incomplete type
      spin_lock_irq(q->queue_lock);
                     ^
>> drivers/mmc/core/queue.c:64:3: error: implicit declaration of function 'blk_fetch_request' [-Werror=implicit-function-declaration]
      req = blk_fetch_request(q);
      ^
>> drivers/mmc/core/queue.c:64:7: warning: assignment makes pointer from integer without a cast
      req = blk_fetch_request(q);
          ^
   drivers/mmc/core/queue.c:79:20: error: dereferencing pointer to incomplete type
      spin_unlock_irq(q->queue_lock);
                       ^
>> drivers/mmc/core/queue.c:110:4: error: implicit declaration of function 'up' [-Werror=implicit-function-declaration]
       up(&mq->thread_sem);
       ^
   drivers/mmc/core/queue.c: In function 'mmc_request_fn':
   drivers/mmc/core/queue.c:128:26: error: dereferencing pointer to incomplete type
     struct mmc_queue *mq = q->queuedata;
                             ^
   drivers/mmc/core/queue.c:133:15: warning: assignment makes pointer from integer without a cast
      while ((req = blk_fetch_request(q)) != NULL) {
                  ^
   drivers/mmc/core/queue.c:134:7: error: dereferencing pointer to incomplete type
       req->rq_flags |= RQF_QUIET;
          ^
>> drivers/mmc/core/queue.c:134:21: error: 'RQF_QUIET' undeclared (first use in this function)
       req->rq_flags |= RQF_QUIET;
                        ^
>> drivers/mmc/core/queue.c:135:4: error: implicit declaration of function '__blk_end_request_all' [-Werror=implicit-function-declaration]
       __blk_end_request_all(req, -EIO);
       ^
   drivers/mmc/core/queue.c: In function 'mmc_queue_setup_discard':
>> drivers/mmc/core/queue.c:175:2: error: implicit declaration of function 'queue_flag_set_unlocked' [-Werror=implicit-function-declaration]
     queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
     ^

vim +/req_op +7 drivers/mmc/core/queue.h

^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16   1  #ifndef MMC_QUEUE_H
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16   2  #define MMC_QUEUE_H
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16   3  
c2df40dfb drivers/mmc/card/queue.h Mike Christie      2016-06-05   4  static inline bool mmc_req_is_special(struct request *req)
c2df40dfb drivers/mmc/card/queue.h Mike Christie      2016-06-05   5  {
3a5e02ced drivers/mmc/card/queue.h Mike Christie      2016-06-05   6  	return req &&
7afafc8a4 drivers/mmc/card/queue.h Adrian Hunter      2016-08-16  @7  		(req_op(req) == REQ_OP_FLUSH ||
7afafc8a4 drivers/mmc/card/queue.h Adrian Hunter      2016-08-16  @8  		 req_op(req) == REQ_OP_DISCARD ||
7afafc8a4 drivers/mmc/card/queue.h Adrian Hunter      2016-08-16  @9  		 req_op(req) == REQ_OP_SECURE_ERASE);
c2df40dfb drivers/mmc/card/queue.h Mike Christie      2016-06-05 @10  }
ef3a69c7a drivers/mmc/card/queue.h Seungwon Jeon      2013-03-14  11  
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16  12  struct request;
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16  13  struct task_struct;
7db3028e0 drivers/mmc/card/queue.h Linus Walleij      2016-11-18  14  struct mmc_blk_data;
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16  15  
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  16  struct mmc_blk_request {
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  17  	struct mmc_request	mrq;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  18  	struct mmc_command	sbc;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  19  	struct mmc_command	cmd;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  20  	struct mmc_command	stop;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  21  	struct mmc_data		data;
b8360a494 drivers/mmc/card/queue.h Adrian Hunter      2015-05-07  22  	int			retune_retry_done;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  23  };
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  24  
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  25  struct mmc_queue_req {
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  26  	struct request		*req;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  27  	struct mmc_blk_request	brq;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  28  	struct scatterlist	*sg;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  29  	char			*bounce_buf;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  30  	struct scatterlist	*bounce_sg;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  31  	unsigned int		bounce_sg_len;
ee8a43a51 drivers/mmc/card/queue.h Per Forlin         2011-07-01  32  	struct mmc_async_req	mmc_active;
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  33  };
97868a2bd drivers/mmc/card/queue.h Per Forlin         2011-07-09  34  
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16  35  struct mmc_queue {
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16  36  	struct mmc_card		*card;
87598a2bd drivers/mmc/mmc_queue.h  Christoph Hellwig  2006-11-13  37  	struct task_struct	*thread;
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16 @38  	struct semaphore	thread_sem;
^1da177e4 drivers/mmc/mmc_queue.h  Linus Torvalds     2005-04-16  39  	unsigned int		flags;
2220eedfd drivers/mmc/card/queue.h Konstantin Dorfman 2013-01-14  40  #define MMC_QUEUE_SUSPENDED	(1 << 0)
2220eedfd drivers/mmc/card/queue.h Konstantin Dorfman 2013-01-14  41  #define MMC_QUEUE_NEW_REQUEST	(1 << 1)

:::::: The code at line 7 was first introduced by commit
:::::: 7afafc8a44bf0ab841b17d450b02aedb3a138985 block: Fix secure erase

:::::: TO: Adrian Hunter <adrian.hunter@intel.com>
:::::: CC: Jens Axboe <axboe@fb.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23791 bytes --]

^ permalink raw reply

* Re: [PATCH 4/7] nonblocking aio: return on congested block device
From: Goldwyn Rodrigues @ 2017-02-15 11:13 UTC (permalink / raw)
  To: Ming Lei, Goldwyn Rodrigues; +Cc: Linux FS Devel, Jan Kara, linux-block
In-Reply-To: <CACVXFVMx4=WBpYq0a3vtQri_D3NCnGJk4J5yyZwHzktTwO1yFw@mail.gmail.com>



On 02/13/2017 09:55 PM, Ming Lei wrote:
> On Tue, Feb 14, 2017 at 10:46 AM, Goldwyn Rodrigues <rgoldwyn@suse.de> wrote:
>> From: Goldwyn Rodrigues <rgoldwyn@suse.com>
>>
>> A new flag BIO_NONBLOCKING is introduced to identify bio's
>> orignating from iocb with IOCB_NONBLOCKING. struct request
>> are requested using BLK_MQ_REQ_NOWAIT if BIO_NONBLOCKING is set.
>>
>> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
>> ---
>>  block/blk-core.c          | 13 +++++++++++--
>>  block/blk-mq.c            | 18 ++++++++++++++++--
>>  fs/direct-io.c            | 11 +++++++++--
>>  include/linux/blk_types.h |  1 +
>>  4 files changed, 37 insertions(+), 6 deletions(-)
>>
>> diff --git a/block/blk-core.c b/block/blk-core.c
>> index 14d7c07..9767573 100644
>> --- a/block/blk-core.c
>> +++ b/block/blk-core.c
>> @@ -1257,6 +1257,11 @@ static struct request *get_request(struct request_queue *q, int op,
>>         if (!IS_ERR(rq))
>>                 return rq;
>>
>> +       if (bio_flagged(bio, BIO_NONBLOCKING)) {
>> +               blk_put_rl(rl);
>> +               return ERR_PTR(-EAGAIN);
>> +       }
>> +
>>         if (!gfpflags_allow_blocking(gfp_mask) || unlikely(blk_queue_dying(q))) {
>>                 blk_put_rl(rl);
>>                 return rq;
>> @@ -2035,7 +2040,7 @@ blk_qc_t generic_make_request(struct bio *bio)
>>         do {
>>                 struct request_queue *q = bdev_get_queue(bio->bi_bdev);
>>
>> -               if (likely(blk_queue_enter(q, false) == 0)) {
>> +               if (likely(blk_queue_enter(q, bio_flagged(bio, BIO_NONBLOCKING)) == 0)) {
>>                         ret = q->make_request_fn(q, bio);
>>
>>                         blk_queue_exit(q);
>> @@ -2044,7 +2049,11 @@ blk_qc_t generic_make_request(struct bio *bio)
>>                 } else {
>>                         struct bio *bio_next = bio_list_pop(current->bio_list);
>>
>> -                       bio_io_error(bio);
>> +                       if (unlikely(bio_flagged(bio, BIO_NONBLOCKING))) {
>> +                               bio->bi_error = -EAGAIN;
>> +                               bio_endio(bio);
>> +                       } else
>> +                               bio_io_error(bio);
>>                         bio = bio_next;
>>                 }
>>         } while (bio);
>> diff --git a/block/blk-mq.c b/block/blk-mq.c
>> index 81caceb..7a7c674 100644
>> --- a/block/blk-mq.c
>> +++ b/block/blk-mq.c
>> @@ -1213,6 +1213,8 @@ static struct request *blk_mq_map_request(struct request_queue *q,
>>
>>         trace_block_getrq(q, bio, op);
>>         blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx);
>> +       if (bio_flagged(bio, BIO_NONBLOCKING))
>> +               alloc_data.flags |= BLK_MQ_REQ_NOWAIT;
>>         rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
>>
>>         data->hctx = alloc_data.hctx;
>> @@ -1286,8 +1288,14 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
>>                 return BLK_QC_T_NONE;
>>
>>         rq = blk_mq_map_request(q, bio, &data);
>> -       if (unlikely(!rq))
>> +       if (unlikely(!rq)) {
>> +               if (bio_flagged(bio, BIO_NONBLOCKING))
>> +                       bio->bi_error = -EAGAIN;
>> +               else
>> +                       bio->bi_error = -EIO;
>> +               bio_endio(bio);
>>                 return BLK_QC_T_NONE;
>> +       }
>>
>>         cookie = blk_tag_to_qc_t(rq->tag, data.hctx->queue_num);
>>
>> @@ -1381,8 +1389,14 @@ static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
>>                 request_count = blk_plug_queued_count(q);
>>
>>         rq = blk_mq_map_request(q, bio, &data);
>> -       if (unlikely(!rq))
>> +       if (unlikely(!rq)) {
>> +               if (bio_flagged(bio, BIO_NONBLOCKING))
>> +                       bio->bi_error = -EAGAIN;
>> +               else
>> +                       bio->bi_error = -EIO;
>> +               bio_endio(bio);
>>                 return BLK_QC_T_NONE;
>> +       }
> 
> There are other places in which blocking may be triggered, such
> as allocating for bio clone, wbt_wait(), and sleep in .make_request(),
> like md, dm and bcache's.
> 
> IMO it should be hard to deal with all, so what is the expection for
> flag of BIO_NONBLOCKING?
> 


This is a part of the effort of making direct AIO nonblocking. I should
have posted all patches to all lists.

BIO_NONBLOCKING is a bio generated from a non-blocking AIO. Ideally it
should bail whenever it sees that it would block and sleep if the
blockqueue is congested (only). While earlier we had thought of limiting
it to get_request(), I expanded it to blk-mq (which now I think may not
be as useful).

>>
>>         cookie = blk_tag_to_qc_t(rq->tag, data.hctx->queue_num);
>>
>> diff --git a/fs/direct-io.c b/fs/direct-io.c
>> index fb9aa16..9997fed 100644
>> --- a/fs/direct-io.c
>> +++ b/fs/direct-io.c
>> @@ -386,6 +386,9 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio,
>>         else
>>                 bio->bi_end_io = dio_bio_end_io;
>>
>> +       if (dio->iocb->ki_flags & IOCB_NONBLOCKING)
>> +               bio_set_flag(bio, BIO_NONBLOCKING);
>> +
>>         sdio->bio = bio;
>>         sdio->logical_offset_in_bio = sdio->cur_page_fs_offset;
>>  }
>> @@ -480,8 +483,12 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
>>         unsigned i;
>>         int err;
>>
>> -       if (bio->bi_error)
>> -               dio->io_error = -EIO;
>> +       if (bio->bi_error) {
>> +               if (bio_flagged(bio, BIO_NONBLOCKING))
>> +                       dio->io_error = bio->bi_error;
>> +               else
>> +                       dio->io_error = -EIO;
>> +       }
>>
>>         if (dio->is_async && dio->op == REQ_OP_READ && dio->should_dirty) {
>>                 err = bio->bi_error;
>> diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
>> index cd395ec..94855cf 100644
>> --- a/include/linux/blk_types.h
>> +++ b/include/linux/blk_types.h
>> @@ -119,6 +119,7 @@ struct bio {
>>  #define BIO_QUIET      6       /* Make BIO Quiet */
>>  #define BIO_CHAIN      7       /* chained bio, ->bi_remaining in effect */
>>  #define BIO_REFFED     8       /* bio has elevated ->bi_cnt */
>> +#define BIO_NONBLOCKING 9      /* don't block over blk device congestion */
>>
>>  /*
>>   * Flags starting here get preserved by bio_reset() - this includes
>> --
>> 2.10.2
>>
> 
> 
> 

-- 
Goldwyn

^ permalink raw reply

* [PATCH] sbitmap: boundary checks for resized bitmap
From: Hannes Reinecke @ 2017-02-15 11:10 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Omar Sandoval, linux-block, Hannes Reinecke, Hannes Reinecke

If the sbitmap gets resized we need to ensure not to overflow
the original allocation. And we should limit the search in
sbitmap_any_bit_set() to the available depth to avoid looking
into unused space.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 include/linux/sbitmap.h |  5 +++++
 lib/sbitmap.c           | 12 +++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index d4e0a20..5ed3815 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -61,6 +61,11 @@ struct sbitmap {
 	unsigned int map_nr;
 
 	/**
+	 * @map_nr: Number of words (cachelines) allocated for the bitmap.
+	 */
+	unsigned int max_map_nr;
+
+	/**
 	 * @map: Allocated bitmap.
 	 */
 	struct sbitmap_word *map;
diff --git a/lib/sbitmap.c b/lib/sbitmap.c
index 55e11c4..f6f18b7 100644
--- a/lib/sbitmap.c
+++ b/lib/sbitmap.c
@@ -44,7 +44,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
 
 	sb->shift = shift;
 	sb->depth = depth;
-	sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);
+	sb->map_nr = sb->max_map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);
 
 	if (depth == 0) {
 		sb->map = NULL;
@@ -70,7 +70,8 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth)
 
 	sb->depth = depth;
 	sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word);
-
+	if (sb->map_nr > sb->max_map_nr)
+		sb->map_nr = sb->max_map_nr;
 	for (i = 0; i < sb->map_nr; i++) {
 		sb->map[i].depth = min(depth, bits_per_word);
 		depth -= sb->map[i].depth;
@@ -145,7 +146,11 @@ bool sbitmap_any_bit_set(const struct sbitmap *sb)
 	unsigned int i;
 
 	for (i = 0; i < sb->map_nr; i++) {
-		if (sb->map[i].word)
+		const struct sbitmap_word *word = &sb->map[i];
+		unsigned long ret;
+
+		ret = find_first_bit(&word->word, word->depth);
+		if (ret < word->depth)
 			return true;
 	}
 	return false;
@@ -187,6 +192,7 @@ void sbitmap_show(struct sbitmap *sb, struct seq_file *m)
 	seq_printf(m, "busy=%u\n", sbitmap_weight(sb));
 	seq_printf(m, "bits_per_word=%u\n", 1U << sb->shift);
 	seq_printf(m, "map_nr=%u\n", sb->map_nr);
+	seq_printf(m, "max_map_nr=%u\n", sb->max_map_nr);
 }
 EXPORT_SYMBOL_GPL(sbitmap_show);
 
-- 
1.8.5.6

^ permalink raw reply related

* Re: [PATCH 4/4] nvme: support ranged discard requests
From: Sagi Grimberg @ 2017-02-15 10:45 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe; +Cc: linux-block, linux-nvme
In-Reply-To: <20170208134650.5380-5-hch@lst.de>

Looks good,

Reviewed-by: Sagi Grimberg <sagi@grimberg.me>

^ permalink raw reply

* Re: support for multi-range discard requests V3
From: Sagi Grimberg @ 2017-02-15 10:43 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe; +Cc: linux-block, linux-nvme
In-Reply-To: <20170208134650.5380-1-hch@lst.de>


> Hi all,
>
> this series adds support for merging discontiguous discard bios into a
> single request if the driver supports it.  This reduces the number of
> discards sent to the device by about a factor of 5-6 for typical
> workloads on NVMe, and for slower devices that use I/O scheduling
> the number will probably be even bigger but I've not implemented
> that support yet.
>
> Changes since V2:
>   - really fix nr of NVMe ranges to 256
>   - free range on error
>
> Changes since V1:
>   - hardcoded max ranges for NVMe to 255
>   - minor cleanups

Oops, reviewed v1 before noticing this one...

^ permalink raw reply

* Re: [PATCH 4/4] nvme: support ranged discard requests
From: Sagi Grimberg @ 2017-02-15 10:42 UTC (permalink / raw)
  To: Christoph Hellwig, Keith Busch; +Cc: Jens Axboe, linux-block, linux-nvme
In-Reply-To: <20170207193439.GA26834@lst.de>



On 07/02/17 21:34, Christoph Hellwig wrote:
> On Tue, Feb 07, 2017 at 01:34:54PM -0500, Keith Busch wrote:
>> On Tue, Feb 07, 2017 at 05:46:58PM +0100, Christoph Hellwig wrote:
>>> @@ -1233,6 +1243,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
>>>  	if (ctrl->vwc & NVME_CTRL_VWC_PRESENT)
>>>  		vwc = true;
>>>  	blk_queue_write_cache(q, vwc, vwc);
>>> +	blk_queue_max_discard_segments(q,
>>> +			PAGE_SIZE / sizeof(struct nvme_dsm_range));
>>
>> We need to use ctrl->page_size rather than PAGE_SIZE.
>
> We need the PAGE_SIZE upper bound because the "special" bvec only
> allows a single page payload.

Shouldn't this be enforced in blk_queue_max_discard_segments() then?

^ permalink raw reply

* Re: [PATCH 3/4] block: optionally merge discontiguous discard bios into a single request
From: Sagi Grimberg @ 2017-02-15 10:36 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe; +Cc: linux-block, linux-nvme
In-Reply-To: <20170207164658.32449-4-hch@lst.de>

Looks good,

Reviewed-by: Sagi Grimberg <sagi@grimbeg.me>

^ permalink raw reply

* Re: [PATCH 2/4] block: enumify ELEVATOR_*_MERGE
From: Sagi Grimberg @ 2017-02-15 10:31 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe; +Cc: linux-block, linux-nvme
In-Reply-To: <20170207164658.32449-3-hch@lst.de>

Looks good,

Reviewed-by: Sagi Grimberg <sagi@grimbeg.me>

^ permalink raw reply

* Re: [PATCH 1/4] block: move req_set_nomerge to blk.h
From: Sagi Grimberg @ 2017-02-15 10:29 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe; +Cc: linux-block, linux-nvme
In-Reply-To: <20170207164658.32449-2-hch@lst.de>

Looks good,

Reviewed-by: Sagi Grimberg <sagi@grimberg.me>

^ permalink raw reply

* Re: [PATCH] mmc: core: make block layer non-optional
From: Arnd Bergmann @ 2017-02-15 10:13 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-mmc, Ulf Hansson, Adrian Hunter, Paolo Valente, linux-block,
	Jens Axboe, Christoph Hellwig
In-Reply-To: <20170215095353.23888-1-linus.walleij@linaro.org>

On Wed, Feb 15, 2017 at 10:53 AM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> I do not know at what point people have wanted to have a system
> with MMC/SD support without the block layer. We are anyway now
> so tightly integrated with the block layer that this is onlt
> teoretical and it makes no sense to have the block layer interface
> as optional.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/mmc/core/Kconfig  | 12 ------------
>  drivers/mmc/core/Makefile |  5 ++---
>  2 files changed, 2 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index cdfa8520a4b1..2920bc4351ed 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -23,19 +23,8 @@ config PWRSEQ_SIMPLE
>           This driver can also be built as a module. If so, the module
>           will be called pwrseq_simple.
>
> -config MMC_BLOCK
> -       tristate "MMC block device driver"
> -       depends on BLOCK

Now you need to move the "depends on BLOCK" into the top-level
option. In theory you could have a system that has no MMC storage
and no block device but boots from NOR flash and uses an SDIO
wifi card, such as this these

https://getchip.com/pages/chip
http://wiki.chumby.com/index.php?title=Main_Page
https://wikidevi.com/wiki/GlobalScale_DreamPlug
https://wikidevi.com/wiki/Linksys_HA1000
https://wikidevi.com/wiki/Google_Chromecast_(H2G2-42)
https://wikidevi.com/wiki/D-Link_DCH-G021

Most are not too memory constrained, but sometimes you want to
squeeze out some kernel memory by turning off CONFIG_BLOCK.

    Arnd

^ permalink raw reply

* Re: [PATCH] mmc: core: make block layer non-optional
From: Johannes Thumshirn @ 2017-02-15 10:00 UTC (permalink / raw)
  To: Linus Walleij, linux-mmc, Ulf Hansson, Adrian Hunter,
	Paolo Valente
  Cc: linux-block, Jens Axboe, Christoph Hellwig, Arnd Bergmann
In-Reply-To: <20170215095353.23888-1-linus.walleij@linaro.org>

Hi Linus,

some nits below:

On 02/15/2017 10:53 AM, Linus Walleij wrote:
> I do not know at what point people have wanted to have a system
> with MMC/SD support without the block layer. We are anyway now
> so tightly integrated with the block layer that this is onlt
                                                        only ^
> teoretical and it makes no sense to have the block layer interface
  ^ theoretical
> as optional.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---

Byte,
	Johannes
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N�rnberg
GF: Felix Imend�rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N�rnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox