Shrink struct request
Subsystems (3)
PATCH 1/1 Shrink struct request
Hi,
This patchset applies on top of what was sent yesterday. It shrinks the size of struct request from 320 to 296 bytes on x86-64 by cleaning up code and removing dead code.
Signature · 1 line
Jens Axboe
PATCH 1/3 Remove ->waiting member from struct request
As the comments indicates in blkdev.h, we can fold it into ->end_io_data usage as that is really what ->waiting is. Fixup the users of blk_end_sync_rq().
--- block/elevator.c | 3 +-- block/ll_rw_blk.c | 11 ++++------- drivers/block/DAC960.c | 2 +- drivers/block/paride/pd.c | 3 +-- drivers/block/pktcdvd.c | 2 +- drivers/ide/ide-io.c | 3 +-- drivers/ide/ide-tape.c | 2 +- include/linux/blkdev.h | 3 +-- 8 files changed, 11 insertions(+), 18 deletions(-)
block/elevator.c +1 -2
@@ -67,8 +67,7 @@ inline int elv_rq_merge_ok(struct reques/* * same device and no special stuff set, merge is ok */ -if (rq->rq_disk == bio->bi_bdev->bd_disk && - !rq->waiting && !rq->special) +if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special)return 1 ;return 0 ;
block/ll_rw_blk.c +4 -7
@@ -291,7 +291,6 @@ static inline void rq_init(request_queue rq->buffer =NULL ; rq->ref_count =1 ; rq->q = q; - rq->waiting =NULL ; rq->special =NULL ; rq->data_len =0 ; rq->data =NULL ;
@@ -2536,10 +2535,9 @@ int blk_execute_rq(request_queue_t *q, s rq->sense_len =0 ; } - rq->waiting = &wait; + rq->end_io_data = &wait;blk_execute_rq_nowait (q, bd_disk, rq, at_head, blk_end_sync_rq);wait_for_completion (&wait); - rq->waiting =NULL ;if (rq->errors) err = -EIO ;
@@ -2703,9 +2701,9 @@ EXPORT_SYMBOL(blk_put_request);*/ void blk_end_sync_rq (struct request *rq,int error) { -struct completion *waiting = rq->waiting; +struct completion *waiting = rq->end_io_data; - rq->waiting =NULL ; + rq->end_io_data =NULL ;__blk_put_request (rq->q, rq);/*
@@ -2756,7 +2754,7 @@ static int attempt_merge(request_queue_tif (rq_data_dir (req) !=rq_data_dir (next) || req->rq_disk != next->rq_disk - || next->waiting || next->special) + || next->special)return 0 ;/*
@@ -2841,7 +2839,6 @@ static void init_request_from_bio(struct req->nr_phys_segments =bio_phys_segments (req->q, bio); req->nr_hw_segments =bio_hw_segments (req->q, bio); req->buffer =bio_data (bio);/* see ->buffer comment above */ - req->waiting =NULL ; req->bio = req->biotail = bio; req->ioprio =bio_prio (bio); req->rq_disk = bio->bi_bdev->bd_disk;
drivers/block/DAC960.c +1 -1
@@ -3331,7 +3331,7 @@ static int DAC960_process_queue(DAC960_C Command->DmaDirection =PCI_DMA_TODEVICE ; Command->CommandType = DAC960_WriteCommand; } - Command->Completion = Request->waiting; + Command->Completion = Request->end_io_data; Command->LogicalDriveNumber = (long )Request->rq_disk->private_data; Command->BlockNumber = Request->sector; Command->BlockCount = Request->nr_sectors;
drivers/block/paride/pd.c +1 -2
@@ -722,11 +722,10 @@ static int pd_special_command(struct pd_ rq.rq_status =RQ_ACTIVE ; rq.rq_disk = disk->gd; rq.ref_count =1 ; - rq.waiting = &wait; + rq.end_io_data = &wait; rq.end_io = blk_end_sync_rq;blk_insert_request (disk->gd->queue, &rq,0 , func);wait_for_completion (&wait); - rq.waiting =NULL ;if (rq.errors) err = -EIO ;blk_put_request (&rq);
drivers/block/pktcdvd.c +1 -1
@@ -375,7 +375,7 @@ static int pkt_generic_packet(struct pkt rq->ref_count++; rq->flags |=REQ_NOMERGE ; - rq->waiting = &wait; + rq->end_io_data = &wait; rq->end_io = blk_end_sync_rq;elv_add_request (q, rq,ELEVATOR_INSERT_BACK ,1 );generic_unplug_device (q);
drivers/ide/ide-io.c +1 -2
@@ -1718,7 +1718,7 @@ int ide_do_drive_cmd (ide_drive_t *drive*/ if (must_wait) { rq->ref_count++; - rq->waiting = &wait; + rq->end_io_data = &wait; rq->end_io = blk_end_sync_rq; }
@@ -1736,7 +1736,6 @@ int ide_do_drive_cmd (ide_drive_t *drive err =0 ;if (must_wait) {wait_for_completion (&wait); - rq->waiting =NULL ;if (rq->errors) err = -EIO ;
drivers/ide/ide-tape.c +1 -1
@@ -2773,7 +2773,7 @@ #if IDETAPE_DEBUG_BUGS return; }#endif /* IDETAPE_DEBUG_BUGS */ - rq->waiting = &wait; + rq->end_io_data = &wait; rq->end_io = blk_end_sync_rq;spin_unlock_irq (&tape->spinlock);wait_for_completion (&wait);
include/linux/blkdev.h +1 -2
@@ -185,7 +185,6 @@ struct request {request_queue_t *q;struct request_list *rl; -struct completion *waiting;void *special;char *buffer;
@@ -204,7 +203,7 @@ struct request {int retries;/* -* completion callback. end_io_data should be folded in with waiting +* completion callback. */ rq_end_io_fn *end_io;void *end_io_data;
Signature · 1 line
1.4.1.ged0e0
PATCH 2/3 Remove struct request_list from struct request
In reply to Jens AxboeIt is always identical to &q->rq, and we only use it for detecting whether this request came out of our mempool or not. So replace it with an additional ->flags bit flag.
--- block/ll_rw_blk.c | 10 ++-------- include/linux/blkdev.h | 3 ++- 2 files changed, 4 insertions(+), 9 deletions(-)
block/ll_rw_blk.c +2 -8
@@ -452,7 +452,6 @@ static void queue_flush(request_queue_t rq->elevator_private =NULL ; rq->elevator_private2 =NULL ; rq->rq_disk = q->bar_rq.rq_disk; - rq->rl =NULL ; rq->end_io = end_io; q->prepare_flush_fn (q, rq);
@@ -478,7 +477,6 @@ static inline struct request *start_orde rq->flags |= q->ordered &QUEUE_ORDERED_FUA ?REQ_FUA :0 ; rq->elevator_private =NULL ; rq->elevator_private2 =NULL ; - rq->rl =NULL ;init_request_from_bio (rq, q->orig_bar_rq->bio); rq->end_io = bar_end_io;
@@ -1984,7 +1982,7 @@ blk_alloc_request(request_queue_t *q, in* first three bits are identical in rq->flags and bio->bi_rw, * see bio.h and blkdev.h */ - rq->flags = rw; + rq->flags = rw |REQ_ALLOCED ;if (priv) {if (unlikely (elv_set_request (q, rq, bio, gfp_mask))) {
@@ -2162,7 +2160,6 @@ rq_starved: ioc->nr_batch_requests--;rq_init (q, rq); - rq->rl = rl;blk_add_trace_generic (q, bio, rw,BLK_TA_GETRQ ); out:
@@ -2646,8 +2643,6 @@ EXPORT_SYMBOL_GPL(disk_round_stats);*/ void __blk_put_request (request_queue_t *q,struct request *req) { -struct request_list *rl = req->rl; -if (unlikely (!q))return ;if (unlikely (--req->ref_count))
@@ -2656,13 +2651,12 @@ void __blk_put_request(request_queue_t *elv_completed_request (q, req); req->rq_status =RQ_INACTIVE ; - req->rl =NULL ;/* * Request may not have originated from ll_rw_blk. if not, * it didn't come out of our reserved rq pools */ -if (rl) { +if (req->flags &REQ_ALLOCED ) {int rw =rq_data_dir (req);int priv = req->flags &REQ_ELVPRIV ;
include/linux/blkdev.h +2 -1
@@ -183,7 +183,6 @@ struct request {int ref_count;request_queue_t *q; -struct request_list *rl;void *special;char *buffer;
@@ -244,6 +243,7 @@ enum rq_flag_bits { __REQ_PM_SHUTDOWN,/* shutdown request */ __REQ_ORDERED_COLOR,/* is before or after barrier */ __REQ_RW_SYNC,/* request is sync (O_DIRECT) */ + __REQ_ALLOCED,/* request came from our alloc pool */ __REQ_NR_BITS, /* stops here */ };
@@ -274,6 +274,7 @@ #define REQ_PM_RESUME (1 << __REQ_PM_RES#define REQ_PM_SHUTDOWN (1 << __REQ_PM_SHUTDOWN)#define REQ_ORDERED_COLOR (1 << __REQ_ORDERED_COLOR)#define REQ_RW_SYNC (1 << __REQ_RW_SYNC) +#define REQ_ALLOCED (1 << __REQ_ALLOCED)/* * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME
Signature · 1 line
1.4.1.ged0e0
PATCH 3/3 Remove ->rq_status from struct request
In reply to Jens AxboeAfter Christophs SCSI change, the only usage left is RQ_ACTIVE and RQ_INACTIVE. The block layer sets RQ_INACTIVE right before freeing the request, so any check for RQ_INACTIVE in a driver is a bug and indicates use-after-free.
So kill/clean the remaining users, straight forward.
--- arch/um/drivers/ubd_kern.c | 2 -- block/ll_rw_blk.c | 3 --- drivers/block/paride/pd.c | 1 - drivers/block/swim3.c | 4 ++-- drivers/block/swim_iop.c | 4 ++-- drivers/fc4/fc.c | 1 - drivers/ide/ide-floppy.c | 3 +-- drivers/ide/ide-io.c | 1 - drivers/ide/ide-tape.c | 4 ++-- drivers/scsi/ide-scsi.c | 2 +- drivers/scsi/scsi.c | 2 +- include/linux/blkdev.h | 13 +++++-------- 12 files changed, 14 insertions(+), 26 deletions(-)
arch/um/drivers/ubd_kern.c +0 -2
@@ -986,8 +986,6 @@ static int prepare_request(struct reques__u64 offset;int len; -if (req->rq_status ==RQ_INACTIVE )return (1 ); -/* This should be impossible now */ if ((rq_data_dir (req) ==WRITE ) && !dev->openflags.w){ printk("Write attempted on readonly ubd device %s\n",
block/ll_rw_blk.c +0 -3
@@ -283,7 +283,6 @@ static inline void rq_init(request_queueINIT_LIST_HEAD (&rq->donelist); rq->errors =0 ; - rq->rq_status =RQ_ACTIVE ; rq->bio = rq->biotail =NULL ;INIT_HLIST_NODE (&rq->hash);RB_CLEAR_NODE (&rq->rb_node);
@@ -2650,8 +2649,6 @@ void __blk_put_request(request_queue_t *elv_completed_request (q, req); - req->rq_status =RQ_INACTIVE ; -/* * Request may not have originated from ll_rw_blk. if not, * it didn't come out of our reserved rq pools
drivers/block/paride/pd.c +0 -1
@@ -719,7 +719,6 @@ static int pd_special_command(struct pd_memset (&rq,0 ,sizeof (rq)); rq.errors =0 ; - rq.rq_status =RQ_ACTIVE ; rq.rq_disk = disk->gd; rq.ref_count =1 ; rq.end_io_data = &wait;
drivers/block/swim3.c +2 -2
@@ -319,8 +319,8 @@ #if 0printk ("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n" , req->rq_disk->disk_name, req->cmd, (long )req->sector, req->nr_sectors, req->buffer); -printk (" rq_status=%d errors=%d current_nr_sectors=%ld\n" , - req->rq_status, req->errors, req->current_nr_sectors); +printk (" errors=%d current_nr_sectors=%ld\n" , + req->errors, req->current_nr_sectors);#endif if (req->sector <0 || req->sector >= fs->total_secs) {
drivers/block/swim_iop.c +2 -2
@@ -529,8 +529,8 @@ #if 0printk ("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n" ,CURRENT ->rq_disk->disk_name,CURRENT ->cmd,CURRENT ->sector,CURRENT ->nr_sectors,CURRENT ->buffer); -printk (" rq_status=%d errors=%d current_nr_sectors=%ld\n" , -CURRENT ->rq_status,CURRENT ->errors,CURRENT ->current_nr_sectors); +printk (" errors=%d current_nr_sectors=%ld\n" , +CURRENT ->errors,CURRENT ->current_nr_sectors);#endif if (CURRENT ->sector <0 ||CURRENT ->sector >= fs->total_secs) {
drivers/fc4/fc.c +0 -1
@@ -974,7 +974,6 @@ #if 0 /* broken junk, but if davem wants*/ fc->rst_pkt->device->host->eh_action = &sem; - fc->rst_pkt->request->rq_status =RQ_SCSI_BUSY ; fc->rst_pkt->done = fcp_scsi_reset_done;
drivers/ide/ide-floppy.c +1 -2
@@ -1281,8 +1281,7 @@ static ide_startstop_t idefloppy_do_requidefloppy_pc_t *pc;unsigned long block = (unsigned long )block_s; -debug_log (KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n" , - rq->rq_status, +debug_log (KERN_INFO "dev: %s, flags: %lx, errors: %d\n" , rq->rq_disk ? rq->rq_disk->disk_name :"?" , rq->flags, rq->errors); debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, "
drivers/ide/ide-io.c +0 -1
@@ -1710,7 +1710,6 @@ int ide_do_drive_cmd (ide_drive_t *driveint must_wait = (action == ide_wait || action == ide_head_wait); rq->errors =0 ; - rq->rq_status =RQ_ACTIVE ;/* * we need to hold an extra reference to request for safe inspection
drivers/ide/ide-tape.c +2 -2
@@ -2423,8 +2423,8 @@ static ide_startstop_t idetape_do_reques#if IDETAPE_DEBUG_LOG #if 0 if (tape->debug_level >=5 ) -printk (KERN_INFO "ide-tape: rq_status: %d, " -"dev: %s, cmd: %ld, errors: %d\n" , rq->rq_status, +printk (KERN_INFO "ide-tape: %d, " +"dev: %s, cmd: %ld, errors: %d\n" , rq->rq_disk->disk_name, rq->cmd[0 ], rq->errors);#endif if (tape->debug_level >=2 )
drivers/scsi/ide-scsi.c +1 -1
@@ -708,7 +708,7 @@ static ide_startstop_t idescsi_issue_pcstatic ide_startstop_t idescsi_do_request (ide_drive_t *drive,struct request *rq,sector_t block) {#if IDESCSI_DEBUG_LOG -printk (KERN_INFO "rq_status: %d, dev: %s, cmd: %x, errors: %d\n" ,rq->rq_status, rq->rq_disk->disk_name,rq->cmd[0 ],rq->errors); +printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n" , rq->rq_disk->disk_name,rq->cmd[0 ],rq->errors);printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n" ,rq->sector,rq->nr_sectors,rq->current_nr_sectors);#endif /* IDESCSI_DEBUG_LOG */
drivers/scsi/scsi.c +1 -1
@@ -1047,7 +1047,7 @@ int scsi_device_cancel(struct scsi_devicspin_lock_irqsave (&sdev->list_lock, flags);list_for_each_entry (scmd, &sdev->cmd_list, list) { -if (scmd->request && scmd->request->rq_status !=RQ_INACTIVE ) { +if (scmd->request) {/* * If we are unable to remove the timer, it means * that the command has already timed out or
include/linux/blkdev.h +5 -8
@@ -160,8 +160,6 @@ struct request {void *completion_data; -int rq_status;/* should split this into a few status bits */ -int errors;struct gendisk *rq_disk;unsigned long start_time;
@@ -179,14 +177,16 @@ struct request {unsigned short ioprio; -int tag; - -int ref_count;request_queue_t *q;void *special;char *buffer; +int tag; +int errors; + +int ref_count; +/* * when request is used as a packet command carrier */
@@ -441,9 +441,6 @@ struct request_queuestruct mutex sysfs_lock; }; -#define RQ_INACTIVE (-1) -#define RQ_ACTIVE 1 -#define QUEUE_FLAG_CLUSTER 0/* cluster several segments into 1 */ #define QUEUE_FLAG_QUEUED 1/* uses generic tag queueing */ #define QUEUE_FLAG_STOPPED 2/* queue is stopped */
Signature · 1 line
1.4.1.ged0e0