![Jens Axboe](/assets/img/avatar_default.png)
Martin reported that his test system would not boot with
current git, it oopsed with this:
BUG: unable to handle kernel paging request at ffff88046c6c9e80
IP: [<ffffffff812971e0>] blk_queue_start_tag+0x90/0x150
PGD 1ddf067 PUD 1de2067 PMD 47fc7d067 PTE 800000046c6c9060
Oops: 0002 [#1] SMP DEBUG_PAGEALLOC
Modules linked in: sd_mod lpfc(+) scsi_transport_fc scsi_tgt oracleasm
rpcsec_gss_krb5 ipv6 igb dca i2c_algo_bit i2c_core hwmon
CPU: 3 PID: 87 Comm: kworker/u17:1 Not tainted 3.14.0+ #246
Hardware name: Supermicro X9DRX+-F/X9DRX+-F, BIOS 3.00 07/09/2013
Workqueue: events_unbound async_run_entry_fn
task: ffff8802743c2150 ti: ffff880273d02000 task.ti: ffff880273d02000
RIP: 0010:[<ffffffff812971e0>] [<ffffffff812971e0>]
blk_queue_start_tag+0x90/0x150
RSP: 0018:ffff880273d03a58 EFLAGS: 00010092
RAX: ffff88046c6c9e78 RBX: ffff880077208e78 RCX: 00000000fffc8da6
RDX: 00000000fffc186d RSI: 0000000000000009 RDI: 00000000fffc8d9d
RBP: ffff880273d03a88 R08: 0000000000000001 R09: ffff8800021c2410
R10: 0000000000000005 R11: 0000000000015b30 R12: ffff88046c5bb8a0
R13: ffff88046c5c0890 R14: 000000000000001e R15: 000000000000001e
FS: 0000000000000000(0000) GS:ffff880277b00000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff88046c6c9e80 CR3: 00000000018f6000 CR4: 00000000000407e0
Stack:
ffff880273d03a98 ffff880474b18800 0000000000000000 ffff880474157000
ffff88046c5c0890 ffff880077208e78 ffff880273d03ae8 ffffffff813b9e62
ffff880200000010 ffff880474b18968 ffff880474b18848 ffff88046c5c0cd8
Call Trace:
[<ffffffff813b9e62>] scsi_request_fn+0xf2/0x510
[<ffffffff81293167>] __blk_run_queue+0x37/0x50
[<ffffffff8129ac43>] blk_execute_rq_nowait+0xb3/0x130
[<ffffffff8129ad24>] blk_execute_rq+0x64/0xf0
[<ffffffff8108d2b0>] ? bit_waitqueue+0xd0/0xd0
[<ffffffff813bba35>] scsi_execute+0xe5/0x180
[<ffffffff813bbe4a>] scsi_execute_req_flags+0x9a/0x110
[<ffffffffa01b1304>] sd_spinup_disk+0x94/0x460 [sd_mod]
[<ffffffff81160000>] ? __unmap_hugepage_range+0x200/0x2f0
[<ffffffffa01b2b9a>] sd_revalidate_disk+0xaa/0x3f0 [sd_mod]
[<ffffffffa01b2fb8>] sd_probe_async+0xd8/0x200 [sd_mod]
[<ffffffff8107703f>] async_run_entry_fn+0x3f/0x140
[<ffffffff8106a1c5>] process_one_work+0x175/0x410
[<ffffffff8106b373>] worker_thread+0x123/0x400
[<ffffffff8106b250>] ? manage_workers+0x160/0x160
[<ffffffff8107104e>] kthread+0xce/0xf0
[<ffffffff81070f80>] ? kthread_freezable_should_stop+0x70/0x70
[<ffffffff815f0bac>] ret_from_fork+0x7c/0xb0
[<ffffffff81070f80>] ? kthread_freezable_should_stop+0x70/0x70
Code: 48 0f ab 11 72 db 48 81 4b 40 00 00 10 00 89 83 08 01 00 00 48 89
df 49 8b 04 24 48 89 1c d0 e8 f7 a8 ff ff 49 8b 85 28 05 00 00 <48> 89
58 08 48 89 03 49 8d 85 28 05 00 00 48 89 43 08 49 89 9d
RIP [<ffffffff812971e0>] blk_queue_start_tag+0x90/0x150
RSP <ffff880273d03a58>
CR2: ffff88046c6c9e80
Martin bisected and found this to be the problem patch;
commit 6d113398dc
Author: Jan Kara <jack@suse.cz>
Date: Mon Feb 24 16:39:54 2014 +0100
block: Stop abusing rq->csd.list in blk-softirq
and the problem was immediately apparent. The patch states that
it is safe to reuse queuelist at completion time, since it is
no longer used. However, that is not true if a device is using
block enabled tagging. If that is the case, then the queuelist
is reused to keep track of busy tags. If a device also ended
up using softirq completions, we'd reuse ->queuelist for the
IPI handling while block tagging was still using it. Boom.
Fix this by adding a new ipi_list list head, and share the
memory used with the request hash table. The hash table is
never used after the request is moved to the dispatch list,
which happens long before any potential completion of the
request. Add a new request bit for this, so we don't have
cases that check rq->hash while it could potentially have
been reused for the IPI completion.
Reported-by: Martin K. Petersen <martin.petersen@oracle.com>
Tested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
248 lines
8 KiB
C
248 lines
8 KiB
C
/*
|
|
* Block data types and constants. Directly include this file only to
|
|
* break include dependency loop.
|
|
*/
|
|
#ifndef __LINUX_BLK_TYPES_H
|
|
#define __LINUX_BLK_TYPES_H
|
|
|
|
#ifdef CONFIG_BLOCK
|
|
|
|
#include <linux/types.h>
|
|
|
|
struct bio_set;
|
|
struct bio;
|
|
struct bio_integrity_payload;
|
|
struct page;
|
|
struct block_device;
|
|
struct io_context;
|
|
struct cgroup_subsys_state;
|
|
typedef void (bio_end_io_t) (struct bio *, int);
|
|
typedef void (bio_destructor_t) (struct bio *);
|
|
|
|
/*
|
|
* was unsigned short, but we might as well be ready for > 64kB I/O pages
|
|
*/
|
|
struct bio_vec {
|
|
struct page *bv_page;
|
|
unsigned int bv_len;
|
|
unsigned int bv_offset;
|
|
};
|
|
|
|
struct bvec_iter {
|
|
sector_t bi_sector; /* device address in 512 byte
|
|
sectors */
|
|
unsigned int bi_size; /* residual I/O count */
|
|
|
|
unsigned int bi_idx; /* current index into bvl_vec */
|
|
|
|
unsigned int bi_bvec_done; /* number of bytes completed in
|
|
current bvec */
|
|
};
|
|
|
|
/*
|
|
* main unit of I/O for the block layer and lower layers (ie drivers and
|
|
* stacking drivers)
|
|
*/
|
|
struct bio {
|
|
struct bio *bi_next; /* request queue link */
|
|
struct block_device *bi_bdev;
|
|
unsigned long bi_flags; /* status, command, etc */
|
|
unsigned long bi_rw; /* bottom bits READ/WRITE,
|
|
* top bits priority
|
|
*/
|
|
|
|
struct bvec_iter bi_iter;
|
|
|
|
/* Number of segments in this BIO after
|
|
* physical address coalescing is performed.
|
|
*/
|
|
unsigned int bi_phys_segments;
|
|
|
|
/*
|
|
* To keep track of the max segment size, we account for the
|
|
* sizes of the first and last mergeable segments in this bio.
|
|
*/
|
|
unsigned int bi_seg_front_size;
|
|
unsigned int bi_seg_back_size;
|
|
|
|
atomic_t bi_remaining;
|
|
|
|
bio_end_io_t *bi_end_io;
|
|
|
|
void *bi_private;
|
|
#ifdef CONFIG_BLK_CGROUP
|
|
/*
|
|
* Optional ioc and css associated with this bio. Put on bio
|
|
* release. Read comment on top of bio_associate_current().
|
|
*/
|
|
struct io_context *bi_ioc;
|
|
struct cgroup_subsys_state *bi_css;
|
|
#endif
|
|
#if defined(CONFIG_BLK_DEV_INTEGRITY)
|
|
struct bio_integrity_payload *bi_integrity; /* data integrity */
|
|
#endif
|
|
|
|
unsigned short bi_vcnt; /* how many bio_vec's */
|
|
|
|
/*
|
|
* Everything starting with bi_max_vecs will be preserved by bio_reset()
|
|
*/
|
|
|
|
unsigned short bi_max_vecs; /* max bvl_vecs we can hold */
|
|
|
|
atomic_t bi_cnt; /* pin count */
|
|
|
|
struct bio_vec *bi_io_vec; /* the actual vec list */
|
|
|
|
struct bio_set *bi_pool;
|
|
|
|
/*
|
|
* We can inline a number of vecs at the end of the bio, to avoid
|
|
* double allocations for a small number of bio_vecs. This member
|
|
* MUST obviously be kept at the very end of the bio.
|
|
*/
|
|
struct bio_vec bi_inline_vecs[0];
|
|
};
|
|
|
|
#define BIO_RESET_BYTES offsetof(struct bio, bi_max_vecs)
|
|
|
|
/*
|
|
* bio flags
|
|
*/
|
|
#define BIO_UPTODATE 0 /* ok after I/O completion */
|
|
#define BIO_RW_BLOCK 1 /* RW_AHEAD set, and read/write would block */
|
|
#define BIO_EOF 2 /* out-out-bounds error */
|
|
#define BIO_SEG_VALID 3 /* bi_phys_segments valid */
|
|
#define BIO_CLONED 4 /* doesn't own data */
|
|
#define BIO_BOUNCED 5 /* bio is a bounce bio */
|
|
#define BIO_USER_MAPPED 6 /* contains user pages */
|
|
#define BIO_EOPNOTSUPP 7 /* not supported */
|
|
#define BIO_NULL_MAPPED 8 /* contains invalid user pages */
|
|
#define BIO_FS_INTEGRITY 9 /* fs owns integrity data, not block layer */
|
|
#define BIO_QUIET 10 /* Make BIO Quiet */
|
|
#define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */
|
|
#define BIO_SNAP_STABLE 12 /* bio data must be snapshotted during write */
|
|
|
|
/*
|
|
* Flags starting here get preserved by bio_reset() - this includes
|
|
* BIO_POOL_IDX()
|
|
*/
|
|
#define BIO_RESET_BITS 13
|
|
#define BIO_OWNS_VEC 13 /* bio_free() should free bvec */
|
|
|
|
#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
|
|
|
|
/*
|
|
* top 4 bits of bio flags indicate the pool this bio came from
|
|
*/
|
|
#define BIO_POOL_BITS (4)
|
|
#define BIO_POOL_NONE ((1UL << BIO_POOL_BITS) - 1)
|
|
#define BIO_POOL_OFFSET (BITS_PER_LONG - BIO_POOL_BITS)
|
|
#define BIO_POOL_MASK (1UL << BIO_POOL_OFFSET)
|
|
#define BIO_POOL_IDX(bio) ((bio)->bi_flags >> BIO_POOL_OFFSET)
|
|
|
|
#endif /* CONFIG_BLOCK */
|
|
|
|
/*
|
|
* Request flags. For use in the cmd_flags field of struct request, and in
|
|
* bi_rw of struct bio. Note that some flags are only valid in either one.
|
|
*/
|
|
enum rq_flag_bits {
|
|
/* common flags */
|
|
__REQ_WRITE, /* not set, read. set, write */
|
|
__REQ_FAILFAST_DEV, /* no driver retries of device errors */
|
|
__REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
|
|
__REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */
|
|
|
|
__REQ_SYNC, /* request is sync (sync write or read) */
|
|
__REQ_META, /* metadata io request */
|
|
__REQ_PRIO, /* boost priority in cfq */
|
|
__REQ_DISCARD, /* request to discard sectors */
|
|
__REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */
|
|
__REQ_WRITE_SAME, /* write same block many times */
|
|
|
|
__REQ_NOIDLE, /* don't anticipate more IO after this one */
|
|
__REQ_FUA, /* forced unit access */
|
|
__REQ_FLUSH, /* request for cache flush */
|
|
|
|
/* bio only flags */
|
|
__REQ_RAHEAD, /* read ahead, can fail anytime */
|
|
__REQ_THROTTLED, /* This bio has already been subjected to
|
|
* throttling rules. Don't do it again. */
|
|
|
|
/* request only flags */
|
|
__REQ_SORTED, /* elevator knows about this request */
|
|
__REQ_SOFTBARRIER, /* may not be passed by ioscheduler */
|
|
__REQ_NOMERGE, /* don't touch this for merging */
|
|
__REQ_STARTED, /* drive already may have started this one */
|
|
__REQ_DONTPREP, /* don't call prep for this one */
|
|
__REQ_QUEUED, /* uses queueing */
|
|
__REQ_ELVPRIV, /* elevator private data attached */
|
|
__REQ_FAILED, /* set if the request failed */
|
|
__REQ_QUIET, /* don't worry about errors */
|
|
__REQ_PREEMPT, /* set for "ide_preempt" requests */
|
|
__REQ_ALLOCED, /* request came from our alloc pool */
|
|
__REQ_COPY_USER, /* contains copies of user pages */
|
|
__REQ_FLUSH_SEQ, /* request for flush sequence */
|
|
__REQ_IO_STAT, /* account I/O stat */
|
|
__REQ_MIXED_MERGE, /* merge of different types, fail separately */
|
|
__REQ_KERNEL, /* direct IO to kernel pages */
|
|
__REQ_PM, /* runtime pm request */
|
|
__REQ_END, /* last of chain of requests */
|
|
__REQ_HASHED, /* on IO scheduler merge hash */
|
|
__REQ_NR_BITS, /* stops here */
|
|
};
|
|
|
|
#define REQ_WRITE (1ULL << __REQ_WRITE)
|
|
#define REQ_FAILFAST_DEV (1ULL << __REQ_FAILFAST_DEV)
|
|
#define REQ_FAILFAST_TRANSPORT (1ULL << __REQ_FAILFAST_TRANSPORT)
|
|
#define REQ_FAILFAST_DRIVER (1ULL << __REQ_FAILFAST_DRIVER)
|
|
#define REQ_SYNC (1ULL << __REQ_SYNC)
|
|
#define REQ_META (1ULL << __REQ_META)
|
|
#define REQ_PRIO (1ULL << __REQ_PRIO)
|
|
#define REQ_DISCARD (1ULL << __REQ_DISCARD)
|
|
#define REQ_WRITE_SAME (1ULL << __REQ_WRITE_SAME)
|
|
#define REQ_NOIDLE (1ULL << __REQ_NOIDLE)
|
|
|
|
#define REQ_FAILFAST_MASK \
|
|
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
|
|
#define REQ_COMMON_MASK \
|
|
(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
|
|
REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \
|
|
REQ_SECURE)
|
|
#define REQ_CLONE_MASK REQ_COMMON_MASK
|
|
|
|
#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME)
|
|
|
|
/* This mask is used for both bio and request merge checking */
|
|
#define REQ_NOMERGE_FLAGS \
|
|
(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
|
|
|
|
#define REQ_RAHEAD (1ULL << __REQ_RAHEAD)
|
|
#define REQ_THROTTLED (1ULL << __REQ_THROTTLED)
|
|
|
|
#define REQ_SORTED (1ULL << __REQ_SORTED)
|
|
#define REQ_SOFTBARRIER (1ULL << __REQ_SOFTBARRIER)
|
|
#define REQ_FUA (1ULL << __REQ_FUA)
|
|
#define REQ_NOMERGE (1ULL << __REQ_NOMERGE)
|
|
#define REQ_STARTED (1ULL << __REQ_STARTED)
|
|
#define REQ_DONTPREP (1ULL << __REQ_DONTPREP)
|
|
#define REQ_QUEUED (1ULL << __REQ_QUEUED)
|
|
#define REQ_ELVPRIV (1ULL << __REQ_ELVPRIV)
|
|
#define REQ_FAILED (1ULL << __REQ_FAILED)
|
|
#define REQ_QUIET (1ULL << __REQ_QUIET)
|
|
#define REQ_PREEMPT (1ULL << __REQ_PREEMPT)
|
|
#define REQ_ALLOCED (1ULL << __REQ_ALLOCED)
|
|
#define REQ_COPY_USER (1ULL << __REQ_COPY_USER)
|
|
#define REQ_FLUSH (1ULL << __REQ_FLUSH)
|
|
#define REQ_FLUSH_SEQ (1ULL << __REQ_FLUSH_SEQ)
|
|
#define REQ_IO_STAT (1ULL << __REQ_IO_STAT)
|
|
#define REQ_MIXED_MERGE (1ULL << __REQ_MIXED_MERGE)
|
|
#define REQ_SECURE (1ULL << __REQ_SECURE)
|
|
#define REQ_KERNEL (1ULL << __REQ_KERNEL)
|
|
#define REQ_PM (1ULL << __REQ_PM)
|
|
#define REQ_END (1ULL << __REQ_END)
|
|
#define REQ_HASHED (1ULL << __REQ_HASHED)
|
|
|
|
#endif /* __LINUX_BLK_TYPES_H */
|