ide-tape: remove pipeline functionality-v3
Subsystems (2)
cover ide-tape: remove pipeline functionality-v3
Hi Bart,
here's the rest of the pipeline removal series. What's left is to rewrite the whole allocation logic around tape->merge_stage and all the other small buffers so that we can get at least some sanity into the driver before working on it any further :).
Documentation/ide/ide-tape.txt | 211 ++++--------- drivers/ide/ide-tape.c | 689 ++-------------------------------------- 2 files changed, 99 insertions(+), 801 deletions(-)
PATCH 1/17 ide-tape: remove unused parameter from idetape_copy_stage_to_user
--- drivers/ide/ide-tape.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-)
drivers/ide/ide-tape.c +4 -7
@@ -1619,7 +1619,7 @@ static int idetape_copy_stage_from_user(idetape_tape_t *tape, }static int idetape_copy_stage_to_user (idetape_tape_t *tape,char __user *buf, -idetape_stage_t *stage,int n) +int n) {struct idetape_bh *bh = tape->bh;int count;
@@ -2493,8 +2493,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,if (tape->merge_stage_size) { actually_read =min ((unsigned int )(tape->merge_stage_size), (unsigned int )count); -if (idetape_copy_stage_to_user (tape, buf, tape->merge_stage, - actually_read)) +if (idetape_copy_stage_to_user (tape, buf, actually_read)) ret = -EFAULT ; buf += actually_read; tape->merge_stage_size -= actually_read;
@@ -2504,8 +2503,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, bytes_read =idetape_add_chrdev_read_request (drive, ctl);if (bytes_read <=0 ) goto finish; -if (idetape_copy_stage_to_user (tape, buf, tape->merge_stage, - bytes_read)) +if (idetape_copy_stage_to_user (tape, buf, bytes_read)) ret = -EFAULT ; buf += bytes_read; count -= bytes_read;
@@ -2516,8 +2514,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,if (bytes_read <=0 ) goto finish; temp =min ((unsigned long )count, (unsigned long )bytes_read); -if (idetape_copy_stage_to_user (tape, buf, tape->merge_stage, - temp)) +if (idetape_copy_stage_to_user (tape, buf, temp)) ret = -EFAULT ; actually_read += temp; tape->merge_stage_size = bytes_read-temp;
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 01/17] ide-tape: remove unused parameter from idetape_copy_stage_to_user
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 2/17 ide-tape: remove unused parameter from idetape_copy_stage_from_user
In reply to Borislav Petkov--- drivers/ide/ide-tape.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-)
drivers/ide/ide-tape.c +4 -7
@@ -1587,7 +1587,7 @@ abort: }static int idetape_copy_stage_from_user (idetape_tape_t *tape, -idetape_stage_t *stage,const char __user *buf,int n) +const char __user *buf,int n) {struct idetape_bh *bh = tape->bh;int count;
@@ -2588,8 +2588,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, actually_written =min ((unsigned int ) (tape->stage_size - tape->merge_stage_size), (unsigned int )count); -if (idetape_copy_stage_from_user (tape, tape->merge_stage, buf, - actually_written)) +if (idetape_copy_stage_from_user (tape, buf, actually_written)) ret = -EFAULT ; buf += actually_written; tape->merge_stage_size += actually_written;
@@ -2605,8 +2604,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, }while (count >= tape->stage_size) {ssize_t retval; -if (idetape_copy_stage_from_user (tape, tape->merge_stage, buf, - tape->stage_size)) +if (idetape_copy_stage_from_user (tape, buf, tape->stage_size)) ret = -EFAULT ; buf += tape->stage_size; count -= tape->stage_size;
@@ -2617,8 +2615,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, }if (count) { actually_written += count; -if (idetape_copy_stage_from_user (tape, tape->merge_stage, buf, - count)) +if (idetape_copy_stage_from_user (tape, buf, count)) ret = -EFAULT ; tape->merge_stage_size += count; }
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 02/17] ide-tape: remove unused parameter from idetape_copy_stage_from_user
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 3/17 ide-tape: remove idetape_discard_read_pipeline()
In reply to Borislav PetkovNow that we don't queue any more requests on the pipeline we don't need to discard it anymore. Also, remove __idetape_discard_read_pipeline() too.
--- drivers/ide/ide-tape.c | 92 +---------------------------------------------- 1 files changed, 2 insertions(+), 90 deletions(-)
drivers/ide/ide-tape.c +2 -90
@@ -1875,52 +1875,6 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive,return 1 ; } -static int __idetape_discard_read_pipeline (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -unsigned long flags; -int cnt; - -if (tape->chrdev_dir !=IDETAPE_DIR_READ ) -return 0 ; - -/* Remove merge stage. */ - cnt = tape->merge_stage_size / tape->blk_size; -if (test_and_clear_bit (IDETAPE_FLAG_FILEMARK , &tape->flags)) - ++cnt;/* Filemarks count as 1 sector */ - tape->merge_stage_size =0 ; -if (tape->merge_stage !=NULL ) { -__idetape_kfree_stage (tape->merge_stage); - tape->merge_stage =NULL ; - } - -/* Clear pipeline flags. */ -clear_bit (IDETAPE_FLAG_PIPELINE_ERR , &tape->flags); - tape->chrdev_dir =IDETAPE_DIR_NONE ; - -/* Remove pipeline stages. */ -if (tape->first_stage ==NULL ) -return 0 ; - -spin_lock_irqsave (&tape->lock, flags); - tape->next_stage =NULL ; -if (test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) -idetape_wait_for_request (drive, tape->active_data_rq); -spin_unlock_irqrestore (&tape->lock, flags); - -while (tape->first_stage !=NULL ) { -struct request *rq_ptr = &tape->first_stage->rq; - - cnt += rq_ptr->nr_sectors - rq_ptr->current_nr_sectors; -if (rq_ptr->errors ==IDETAPE_ERROR_FILEMARK ) - ++cnt; -idetape_remove_stage_head (drive); - } - tape->nr_pending_stages =0 ; - tape->max_stages = tape->min_pipeline; -return cnt; -} -/* * Position the tape to the requested block using the LOCATE packet command. * A READ POSITION command is then issued to check where we are positioned. Like
@@ -1930,12 +1884,9 @@ static int __idetape_discard_read_pipeline(ide_drive_t *drive)static int idetape_position_tape (ide_drive_t *drive,unsigned int block,u8 partition,int skip) { -idetape_tape_t *tape = drive->driver_data; -int retval;struct ide_atapi_pc pc; +int retval; -if (tape->chrdev_dir ==IDETAPE_DIR_READ ) -__idetape_discard_read_pipeline (drive);idetape_wait_ready (drive,60 *5 *HZ );idetape_create_locate_cmd (drive, &pc, block, partition, skip); retval =idetape_queue_pc_tail (drive, &pc);
@@ -1946,25 +1897,6 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,return (idetape_queue_pc_tail (drive, &pc)); } -static void idetape_discard_read_pipeline (ide_drive_t *drive, -int restore_position) -{ -idetape_tape_t *tape = drive->driver_data; -int cnt; -int seek, position; - - cnt =__idetape_discard_read_pipeline (drive); -if (restore_position) { - position =idetape_read_position (drive); - seek = position > cnt ? position - cnt :0 ; -if (idetape_position_tape (drive, seek,0 ,0 )) { -printk (KERN_INFO "ide-tape: %s: position_tape failed in" -" discard_pipeline()\n" , tape->name); -return ; - } - } -} -/* * Generate a read/write request for the block device interface and wait for it * to be serviced.
@@ -2406,11 +2338,6 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,* pipeline. There is no point in allowing the * drive to continue reading any farther, so we * stop the pipeline. -* -* This section should be moved to a separate -* subroutine because similar operations are -* done in __idetape_discard_read_pipeline(), -* for example. */ tape->next_stage =NULL ;spin_unlock_irqrestore (&tape->lock, flags);
@@ -2423,7 +2350,6 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, ++count;idetape_remove_stage_head (drive); } -idetape_discard_read_pipeline (drive,0 ); }/*
@@ -2547,8 +2473,6 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,/* Initialize write operation */ if (tape->chrdev_dir !=IDETAPE_DIR_WRITE ) { -if (tape->chrdev_dir ==IDETAPE_DIR_READ ) -idetape_discard_read_pipeline (drive,1 );if (tape->merge_stage || tape->merge_stage_size) {printk (KERN_ERR "ide-tape: merge_stage_size " "should be 0 now\n" );
@@ -2675,7 +2599,6 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)case MTWEOF :if (tape->write_prot)return -EACCES ; -idetape_discard_read_pipeline (drive,1 );for (i =0 ; i < mt_count; i++) { retval =idetape_write_filemark (drive);if (retval)
@@ -2683,12 +2606,10 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) }return 0 ;case MTREW : -idetape_discard_read_pipeline (drive,0 );if (idetape_rewind_tape (drive))return -EIO ;return 0 ;case MTLOAD : -idetape_discard_read_pipeline (drive,0 );idetape_create_load_unload_cmd (drive, &pc,IDETAPE_LU_LOAD_MASK );return idetape_queue_pc_tail (drive, &pc);
@@ -2703,7 +2624,6 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)if (!idetape_queue_pc_tail (drive, &pc)) tape->door_locked =DOOR_UNLOCKED ; } -idetape_discard_read_pipeline (drive,0 );idetape_create_load_unload_cmd (drive, &pc, !IDETAPE_LU_LOAD_MASK ); retval =idetape_queue_pc_tail (drive, &pc);
@@ -2711,10 +2631,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)clear_bit (IDETAPE_FLAG_MEDIUM_PRESENT , &tape->flags);return retval;case MTNOP : -idetape_discard_read_pipeline (drive,0 );return idetape_flush_tape_buffers (drive);case MTRETEN : -idetape_discard_read_pipeline (drive,0 );idetape_create_load_unload_cmd (drive, &pc,IDETAPE_LU_RETENSION_MASK |IDETAPE_LU_LOAD_MASK );return idetape_queue_pc_tail (drive, &pc);
@@ -2736,11 +2654,9 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)set_bit (IDETAPE_FLAG_DETECT_BS , &tape->flags);return 0 ;case MTSEEK : -idetape_discard_read_pipeline (drive,0 );return idetape_position_tape (drive, mt_count * tape->user_bs_factor, tape->partition,0 );case MTSETPART : -idetape_discard_read_pipeline (drive,0 );return idetape_position_tape (drive,0 , mt_count,0 );case MTFSR :case MTBSR :
@@ -2821,8 +2737,6 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,return -EFAULT ;return 0 ;default : -if (tape->chrdev_dir ==IDETAPE_DIR_READ ) -idetape_discard_read_pipeline (drive,1 );return idetape_blkdev_ioctl (drive, cmd, arg); } }
@@ -2966,9 +2880,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)if (tape->chrdev_dir ==IDETAPE_DIR_WRITE )idetape_write_release (drive, minor);if (tape->chrdev_dir ==IDETAPE_DIR_READ ) { -if (minor <128 ) -idetape_discard_read_pipeline (drive,1 ); -else +if (minor >=128 )idetape_wait_for_pipeline (drive); }
Signature · 1 line
1.5.4.1
Re: [PATCH 03/17] ide-tape: remove idetape_discard_read_pipeline()
Quoted 20 lines · Borislav Petkov
Now that we don't queue any more requests on the pipeline we don't need to discard it anymore. Also, remove
__idetape_discard_read_pipeline()too.Signed-off-by Borislav Petkov <[email protected]>--- drivers/ide/ide-tape.c | 92 +---------------------------------------------- 1 files changed, 2 insertions(+), 90 deletions(-)drivers/ide/ide-tape.c +0
-4@@ -1875,52 +1875,6 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive,return 1 ; } -static int __idetape_discard_read_pipeline (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -unsigned long flags;
drivers/ide/ide-tape.c static int idetape_create_prevent_cmd(ide_drive_t *drive, · line 1891
Quoted 10 lines
drivers/ide/ide-tape.c +0
-10-int cnt; - -if (tape->chrdev_dir !=IDETAPE_DIR_READ ) -return 0 ; - -/* Remove merge stage. */ - cnt = tape->merge_stage_size / tape->blk_size; -if (test_and_clear_bit (IDETAPE_FLAG_FILEMARK , &tape->flags)) - ++cnt;/* Filemarks count as 1 sector */ - tape->merge_stage_size =0 ;
->merge_stage_size is still used for accounting and we've just silently deleted code modifying it...
drivers/ide/ide-tape.c static int idetape_create_prevent_cmd(ide_drive_t *drive, · line 1899
Quoted 8 lines
drivers/ide/ide-tape.c +0
-8-if (tape->merge_stage !=NULL ) { -__idetape_kfree_stage (tape->merge_stage); - tape->merge_stage =NULL ; - } - -/* Clear pipeline flags. */ -clear_bit (IDETAPE_FLAG_PIPELINE_ERR , &tape->flags); - tape->chrdev_dir =IDETAPE_DIR_NONE ;
ditto for ->merge_stage and ->chrdev_dir (!)
drivers/ide/ide-tape.c static int idetape_create_prevent_cmd(ide_drive_t *drive, · line 1903
Quoted 3 lines
drivers/ide/ide-tape.c +0
-3-/* Remove pipeline stages. */ -if (tape->first_stage ==NULL ) -return 0 ;
only code below could be safely deleted at the moment (we know that ->first_stage is always NULL)
Quoted 42 lines
drivers/ide/ide-tape.c +1
-25-spin_lock_irqsave (&tape->lock, flags); - tape->next_stage =NULL ; -if (test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) -idetape_wait_for_request (drive, tape->active_data_rq); -spin_unlock_irqrestore (&tape->lock, flags); - -while (tape->first_stage !=NULL ) { -struct request *rq_ptr = &tape->first_stage->rq; - - cnt += rq_ptr->nr_sectors - rq_ptr->current_nr_sectors; -if (rq_ptr->errors ==IDETAPE_ERROR_FILEMARK ) - ++cnt; -idetape_remove_stage_head (drive); - } - tape->nr_pending_stages =0 ; - tape->max_stages = tape->min_pipeline; -return cnt; -} -/* * Position the tape to the requested block using the LOCATE packet command. * A READ POSITION command is then issued to check where we are positioned. Like @@ -1930,12 +1884,9 @@ static int __idetape_discard_read_pipeline(ide_drive_t *drive)static int idetape_position_tape (ide_drive_t *drive,unsigned int block,u8 partition,int skip) { -idetape_tape_t *tape = drive->driver_data; -int retval;struct ide_atapi_pc pc; +int retval; -if (tape->chrdev_dir ==IDETAPE_DIR_READ ) -__idetape_discard_read_pipeline (drive);idetape_wait_ready (drive,60 *5 *HZ );idetape_create_locate_cmd (drive, &pc, block, partition, skip); retval =idetape_queue_pc_tail (drive, &pc);@@ -1946,25 +1897,6 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,return (idetape_queue_pc_tail (drive, &pc)); } -static void idetape_discard_read_pipeline (ide_drive_t *drive, -int restore_position)
drivers/ide/ide-tape.c static int idetape_position_tape(ide_drive_t *drive, unsigned int block, · line 1960
Quoted 10 lines
drivers/ide/ide-tape.c +0
-10-{ -idetape_tape_t *tape = drive->driver_data; -int cnt; -int seek, position; - - cnt =__idetape_discard_read_pipeline (drive); -if (restore_position) { - position =idetape_read_position (drive); - seek = position > cnt ? position - cnt :0 ; -if (idetape_position_tape (drive, seek,0 ,0 )) {
and here we've silently deleted idetape_position_tape() call (for 'restore_position == 1' users)
I just skipped this patch => I had to slightly re-do later patches while merging them...
Quoted 110 lines
drivers/ide/ide-tape.c +1
-28-printk (KERN_INFO "ide-tape: %s: position_tape failed in" -" discard_pipeline()\n" , tape->name); -return ; - } - } -} -/* * Generate a read/write request for the block device interface and wait for it * to be serviced. @@ -2406,11 +2338,6 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,* pipeline. There is no point in allowing the * drive to continue reading any farther, so we * stop the pipeline. -* -* This section should be moved to a separate -* subroutine because similar operations are -* done in __idetape_discard_read_pipeline(), -* for example. */ tape->next_stage =NULL ;spin_unlock_irqrestore (&tape->lock, flags);@@ -2423,7 +2350,6 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, ++count;idetape_remove_stage_head (drive); } -idetape_discard_read_pipeline (drive,0 ); }/* @@ -2547,8 +2473,6 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,/* Initialize write operation */ if (tape->chrdev_dir !=IDETAPE_DIR_WRITE ) { -if (tape->chrdev_dir ==IDETAPE_DIR_READ ) -idetape_discard_read_pipeline (drive,1 );if (tape->merge_stage || tape->merge_stage_size) {printk (KERN_ERR "ide-tape: merge_stage_size " "should be 0 now\n" );@@ -2675,7 +2599,6 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)case MTWEOF :if (tape->write_prot)return -EACCES ; -idetape_discard_read_pipeline (drive,1 );for (i =0 ; i < mt_count; i++) { retval =idetape_write_filemark (drive);if (retval)@@ -2683,12 +2606,10 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) }return 0 ;case MTREW : -idetape_discard_read_pipeline (drive,0 );if (idetape_rewind_tape (drive))return -EIO ;return 0 ;case MTLOAD : -idetape_discard_read_pipeline (drive,0 );idetape_create_load_unload_cmd (drive, &pc,IDETAPE_LU_LOAD_MASK );return idetape_queue_pc_tail (drive, &pc);@@ -2703,7 +2624,6 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)if (!idetape_queue_pc_tail (drive, &pc)) tape->door_locked =DOOR_UNLOCKED ; } -idetape_discard_read_pipeline (drive,0 );idetape_create_load_unload_cmd (drive, &pc, !IDETAPE_LU_LOAD_MASK ); retval =idetape_queue_pc_tail (drive, &pc);@@ -2711,10 +2631,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)clear_bit (IDETAPE_FLAG_MEDIUM_PRESENT , &tape->flags);return retval;case MTNOP : -idetape_discard_read_pipeline (drive,0 );return idetape_flush_tape_buffers (drive);case MTRETEN : -idetape_discard_read_pipeline (drive,0 );idetape_create_load_unload_cmd (drive, &pc,IDETAPE_LU_RETENSION_MASK |IDETAPE_LU_LOAD_MASK );return idetape_queue_pc_tail (drive, &pc);@@ -2736,11 +2654,9 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)set_bit (IDETAPE_FLAG_DETECT_BS , &tape->flags);return 0 ;case MTSEEK : -idetape_discard_read_pipeline (drive,0 );return idetape_position_tape (drive, mt_count * tape->user_bs_factor, tape->partition,0 );case MTSETPART : -idetape_discard_read_pipeline (drive,0 );return idetape_position_tape (drive,0 , mt_count,0 );case MTFSR :case MTBSR :@@ -2821,8 +2737,6 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,return -EFAULT ;return 0 ;default : -if (tape->chrdev_dir ==IDETAPE_DIR_READ ) -idetape_discard_read_pipeline (drive,1 );return idetape_blkdev_ioctl (drive, cmd, arg); } }@@ -2966,9 +2880,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)if (tape->chrdev_dir ==IDETAPE_DIR_WRITE )idetape_write_release (drive, minor);if (tape->chrdev_dir ==IDETAPE_DIR_READ ) { -if (minor <128 ) -idetape_discard_read_pipeline (drive,1 ); -else +if (minor >=128 )idetape_wait_for_pipeline (drive); }
PATCH 4/17 ide-tape: remove idetape_empty_write_pipeline()
In reply to Borislav PetkovIn order _not_ to skip over some pipeline stages left, we carefully flush any remaining ones. Nevertheless, this is only a temporary measure (git-bisect) before removing pipeline functionality completely.
--- drivers/ide/ide-tape.c | 80 ++---------------------------------------------- 1 files changed, 3 insertions(+), 77 deletions(-)
drivers/ide/ide-tape.c +3 -77
@@ -2041,80 +2041,6 @@ static void idetape_wait_for_pipeline(ide_drive_t *drive) } } -static void idetape_empty_write_pipeline (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -int blocks, min; -struct idetape_bh *bh; - -if (tape->chrdev_dir !=IDETAPE_DIR_WRITE ) { -printk (KERN_ERR "ide-tape: bug: Trying to empty write pipeline," -" but we are not writing.\n" ); -return ; - } -if (tape->merge_stage_size > tape->stage_size) { -printk (KERN_ERR "ide-tape: bug: merge_buffer too big\n" ); - tape->merge_stage_size = tape->stage_size; - } -if (tape->merge_stage_size) { - blocks = tape->merge_stage_size / tape->blk_size; -if (tape->merge_stage_size % tape->blk_size) { -unsigned int i; - - blocks++; - i = tape->blk_size - tape->merge_stage_size % - tape->blk_size; - bh = tape->bh->b_reqnext; -while (bh) { -atomic_set (&bh->b_count,0 ); - bh = bh->b_reqnext; - } - bh = tape->bh; -while (i) { -if (bh ==NULL ) { -printk (KERN_INFO "ide-tape: bug," -" bh NULL\n" ); -break ; - } - min =min (i, (unsigned int )(bh->b_size - -atomic_read (&bh->b_count))); -memset (bh->b_data +atomic_read (&bh->b_count), -0 , min); -atomic_add (min, &bh->b_count); - i -= min; - bh = bh->b_reqnext; - } - } - (void )idetape_add_chrdev_write_request (drive, blocks); - tape->merge_stage_size =0 ; - } -idetape_wait_for_pipeline (drive); -if (tape->merge_stage !=NULL ) { -__idetape_kfree_stage (tape->merge_stage); - tape->merge_stage =NULL ; - } -clear_bit (IDETAPE_FLAG_PIPELINE_ERR , &tape->flags); - tape->chrdev_dir =IDETAPE_DIR_NONE ; - -/* -* On the next backup, perform the feedback loop again. (I don't want to -* keep sense information between backups, as some systems are -* constantly on, and the system load can be totally different on the -* next backup). -*/ - tape->max_stages = tape->min_pipeline; -if (tape->first_stage !=NULL || - tape->next_stage !=NULL || - tape->last_stage !=NULL || - tape->nr_stages !=0 ) { -printk (KERN_ERR "ide-tape: ide-tape pipeline bug, " -"first_stage %p, next_stage %p, " -"last_stage %p, nr_stages %d\n" , - tape->first_stage, tape->next_stage, - tape->last_stage, tape->nr_stages); - } -} -static int idetape_init_read (ide_drive_t *drive,int max_stages) {idetape_tape_t *tape = drive->driver_data;
@@ -2123,7 +2049,7 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages)/* Initialize read operation */ if (tape->chrdev_dir !=IDETAPE_DIR_READ ) {if (tape->chrdev_dir ==IDETAPE_DIR_WRITE ) { -idetape_empty_write_pipeline (drive); +idetape_wait_for_pipeline (drive);idetape_flush_tape_buffers (drive); }if (tape->merge_stage || tape->merge_stage_size) {
@@ -2702,7 +2628,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,debug_log (DBG_CHRDEV ,"Enter %s, cmd=%u\n" , __func__, cmd);if (tape->chrdev_dir ==IDETAPE_DIR_WRITE ) { -idetape_empty_write_pipeline (drive); +idetape_wait_for_pipeline (drive);idetape_flush_tape_buffers (drive); }if (cmd ==MTIOCGET || cmd ==MTIOCPOS ) {
@@ -2852,7 +2778,7 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) {idetape_tape_t *tape = drive->driver_data; -idetape_empty_write_pipeline (drive); +idetape_wait_for_pipeline (drive); tape->merge_stage =__idetape_kmalloc_stage (tape,1 ,0 );if (tape->merge_stage !=NULL ) { idetape_pad_zeros(drive, tape->blk_size *
Signature · 1 line
1.5.4.1
Re: [PATCH 04/17] ide-tape: remove idetape_empty_write_pipeline()
Quoted 53 lines · Borislav Petkov
In order _not_ to skip over some pipeline stages left, we carefully flush any remaining ones. Nevertheless, this is only a temporary measure (git-bisect) before removing pipeline functionality completely.
Signed-off-by Borislav Petkov <[email protected]>--- drivers/ide/ide-tape.c | 80 ++---------------------------------------------- 1 files changed, 3 insertions(+), 77 deletions(-)drivers/ide/ide-tape.c +0
-36@@ -2041,80 +2041,6 @@ static void idetape_wait_for_pipeline(ide_drive_t *drive) } } -static void idetape_empty_write_pipeline (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -int blocks, min; -struct idetape_bh *bh; - -if (tape->chrdev_dir !=IDETAPE_DIR_WRITE ) { -printk (KERN_ERR "ide-tape: bug: Trying to empty write pipeline," -" but we are not writing.\n" ); -return ; - } -if (tape->merge_stage_size > tape->stage_size) { -printk (KERN_ERR "ide-tape: bug: merge_buffer too big\n" ); - tape->merge_stage_size = tape->stage_size; - } -if (tape->merge_stage_size) { - blocks = tape->merge_stage_size / tape->blk_size; -if (tape->merge_stage_size % tape->blk_size) { -unsigned int i; - - blocks++; - i = tape->blk_size - tape->merge_stage_size % - tape->blk_size; - bh = tape->bh->b_reqnext; -while (bh) { -atomic_set (&bh->b_count,0 ); - bh = bh->b_reqnext; - } - bh = tape->bh; -while (i) { -if (bh ==NULL ) { -printk (KERN_INFO "ide-tape: bug," -" bh NULL\n" ); -break ; - } - min = min(i, (unsigned int)(bh->b_size -
drivers/ide/ide-tape.c static void idetape_wait_for_pipeline(ide_drive_t *drive) · line 2089
Quoted 10 lines
drivers/ide/ide-tape.c +0
-10- atomic_read(&bh->b_count))); -memset (bh->b_data +atomic_read (&bh->b_count), -0 , min); -atomic_add (min, &bh->b_count); - i -= min; - bh = bh->b_reqnext; - } - } - (void )idetape_add_chrdev_write_request (drive, blocks); - tape->merge_stage_size =0 ;
this patch has the same problems as patch #3 => skipped
Quoted 58 lines
drivers/ide/ide-tape.c +3
-31- } -idetape_wait_for_pipeline (drive); -if (tape->merge_stage !=NULL ) { -__idetape_kfree_stage (tape->merge_stage); - tape->merge_stage =NULL ; - } -clear_bit (IDETAPE_FLAG_PIPELINE_ERR , &tape->flags); - tape->chrdev_dir =IDETAPE_DIR_NONE ; - -/* -* On the next backup, perform the feedback loop again. (I don't want to -* keep sense information between backups, as some systems are -* constantly on, and the system load can be totally different on the -* next backup). -*/ - tape->max_stages = tape->min_pipeline; -if (tape->first_stage !=NULL || - tape->next_stage !=NULL || - tape->last_stage !=NULL || - tape->nr_stages !=0 ) { -printk (KERN_ERR "ide-tape: ide-tape pipeline bug, " -"first_stage %p, next_stage %p, " -"last_stage %p, nr_stages %d\n" , - tape->first_stage, tape->next_stage, - tape->last_stage, tape->nr_stages); - } -} -static int idetape_init_read (ide_drive_t *drive,int max_stages) {idetape_tape_t *tape = drive->driver_data;@@ -2123,7 +2049,7 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages)/* Initialize read operation */ if (tape->chrdev_dir !=IDETAPE_DIR_READ ) {if (tape->chrdev_dir ==IDETAPE_DIR_WRITE ) { -idetape_empty_write_pipeline (drive); +idetape_wait_for_pipeline (drive);idetape_flush_tape_buffers (drive); }if (tape->merge_stage || tape->merge_stage_size) {@@ -2702,7 +2628,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,debug_log (DBG_CHRDEV ,"Enter %s, cmd=%u\n" , __func__, cmd);if (tape->chrdev_dir ==IDETAPE_DIR_WRITE ) { -idetape_empty_write_pipeline (drive); +idetape_wait_for_pipeline (drive);idetape_flush_tape_buffers (drive); }if (cmd ==MTIOCGET || cmd ==MTIOCPOS ) {@@ -2852,7 +2778,7 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) {idetape_tape_t *tape = drive->driver_data; -idetape_empty_write_pipeline (drive); +idetape_wait_for_pipeline (drive); tape->merge_stage =__idetape_kmalloc_stage (tape,1 ,0 );if (tape->merge_stage !=NULL ) { idetape_pad_zeros(drive, tape->blk_size *
PATCH 5/17 ide-tape: remove pipeline-specific code in idetape_space_over_filemarks()
In reply to Borislav PetkovSince we don't do pipeline read-ahead anymore, we don't have to look for filemarks we have crossed. Therefore, remove the code chunk that does that and pass on the command to the tape. As a side effect, remove unused idetape_wait_first_stage().
--- drivers/ide/ide-tape.c | 52 ------------------------------------------------ 1 files changed, 0 insertions(+), 52 deletions(-)
drivers/ide/ide-tape.c +0 -52
@@ -1983,19 +1983,6 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) pc->idetape_callback = &idetape_pc_callback; } -static void idetape_wait_first_stage (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -unsigned long flags; - -if (tape->first_stage ==NULL ) -return ; -spin_lock_irqsave (&tape->lock, flags); -if (tape->active_stage == tape->first_stage) -idetape_wait_for_request (drive, tape->active_data_rq); -spin_unlock_irqrestore (&tape->lock, flags); -} -/* Queue up a character device originated write request. */ static int idetape_add_chrdev_write_request (ide_drive_t *drive,int blocks) {
@@ -2221,19 +2208,11 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,return 0 ; } -/* -* The function below is now a bit more complicated than just passing the -* command to the tape since we may have crossed some filemarks during our -* pipelined read-ahead mode. As a minor side effect, the pipeline enables us to -* support MTFSFM when the filemark is in our internal pipeline even if the tape -* doesn't support spacing over filemarks in the reverse direction. -*/ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_count) {idetape_tape_t *tape = drive->driver_data;struct ide_atapi_pc pc; -unsigned long flags;int retval, count =0 ;int sprev = !!(tape->caps[4 ] &0x20 );
@@ -2246,42 +2225,11 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, }if (tape->chrdev_dir ==IDETAPE_DIR_READ ) { -/* its a read-ahead buffer, scan it for crossed filemarks. */ tape->merge_stage_size =0 ;if (test_and_clear_bit (IDETAPE_FLAG_FILEMARK , &tape->flags)) ++count; -while (tape->first_stage !=NULL ) { -if (count == mt_count) { -if (mt_op ==MTFSFM ) -set_bit (IDETAPE_FLAG_FILEMARK , - &tape->flags); -return 0 ; - } -spin_lock_irqsave (&tape->lock, flags); -if (tape->first_stage == tape->active_stage) { -/* -* We have reached the active stage in the read -* pipeline. There is no point in allowing the -* drive to continue reading any farther, so we -* stop the pipeline. -*/ - tape->next_stage =NULL ; -spin_unlock_irqrestore (&tape->lock, flags); -idetape_wait_first_stage (drive); - tape->next_stage = tape->first_stage->next; - }else -spin_unlock_irqrestore (&tape->lock, flags); -if (tape->first_stage->rq.errors == -IDETAPE_ERROR_FILEMARK ) - ++count; -idetape_remove_stage_head (drive); - } } -/* -* The filemark was not found in our internal pipeline; now we can issue -* the space command. -*/ switch (mt_op) {case MTFSF :case MTBSF :
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 05/17] ide-tape: remove pipeline-specific code in idetape_space_over_filemarks()
Quoted 6 lines · Borislav Petkov
Since we don't do pipeline read-ahead anymore, we don't have to look for filemarks we have crossed. Therefore, remove the code chunk that does that and pass on the command to the tape. As a side effect, remove unused
idetape_wait_first_stage().Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 6/17 ide-tape: remove idetape_pipeline_size()
In reply to Borislav PetkovThe computation of the block offset of the the tape position (MTIOCPOS, MTIOCGET) is not influenced by the stages queued in the pipeline anymore but by the size of the current buffer which is going to be sent to the drive.
--- drivers/ide/ide-tape.c | 23 +---------------------- 1 files changed, 1 insertions(+), 22 deletions(-)
drivers/ide/ide-tape.c +1 -22
@@ -2128,27 +2128,6 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount) } } -static int idetape_pipeline_size (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -idetape_stage_t *stage; -struct request *rq; -int size =0 ; - -idetape_wait_for_pipeline (drive); - stage = tape->first_stage; -while (stage !=NULL ) { - rq = &stage->rq; - size += tape->blk_size * (rq->nr_sectors - - rq->current_nr_sectors); -if (rq->errors ==IDETAPE_ERROR_FILEMARK ) - size += tape->blk_size; - stage = stage->next; - } - size += tape->merge_stage_size; -return size; -} -/* * Rewinds the tape to the Beginning Of the current Partition (BOP). We * currently support only one partition.
@@ -2580,7 +2559,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,idetape_flush_tape_buffers (drive); }if (cmd ==MTIOCGET || cmd ==MTIOCPOS ) { - block_offset =idetape_pipeline_size (drive) / + block_offset = tape->merge_stage_size / (tape->blk_size * tape->user_bs_factor); position =idetape_read_position (drive);if (position <0 )
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 06/17] ide-tape: remove idetape_pipeline_size()
Quoted 5 lines · Borislav Petkov
The computation of the block offset of the the tape position (MTIOCPOS, MTIOCGET) is not influenced by the stages queued in the pipeline anymore but by the size of the current buffer which is going to be sent to the drive.
Signed-off-by Borislav Petkov <[email protected]>
applied
[ I resurrected deleted idetape_wait_for_pipeline() call ]
PATCH 7/17 ide-tape: remove idetape_remove_stage_head()
In reply to Borislav Petkov--- drivers/ide/ide-tape.c | 39 --------------------------------------- 1 files changed, 0 insertions(+), 39 deletions(-)
drivers/ide/ide-tape.c +0 -39
@@ -692,41 +692,6 @@ static void idetape_kfree_stage(idetape_tape_t *tape, idetape_stage_t *stage) }/* -* Remove tape->first_stage from the pipeline. The caller should avoid race -* conditions. -*/ -static void idetape_remove_stage_head (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -idetape_stage_t *stage; - -debug_log (DBG_PROCS ,"Enter %s\n" , __func__); - -if (tape->first_stage ==NULL ) { -printk (KERN_ERR "ide-tape: bug: tape->first_stage is NULL\n" ); -return ; - } -if (tape->active_stage == tape->first_stage) { -printk (KERN_ERR "ide-tape: bug: Trying to free our active " -"pipeline stage\n" ); -return ; - } - stage = tape->first_stage; - tape->first_stage = stage->next; -idetape_kfree_stage (tape, stage); - tape->nr_stages--; -if (tape->first_stage ==NULL ) { - tape->last_stage =NULL ; -if (tape->next_stage !=NULL ) -printk (KERN_ERR "ide-tape: bug: tape->next_stage !=" -" NULL\n" ); -if (tape->nr_stages) -printk (KERN_ERR "ide-tape: bug: nr_stages should be 0 " -"now\n" ); - } -} - -/* * This will free all the pipeline stages starting from new_last_stage->next * to the end of the list, and point tape->last_stage to new_last_stage. */
@@ -762,7 +727,6 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)idetape_tape_t *tape = drive->driver_data;unsigned long flags;int error; -int remove_stage =0 ;idetape_stage_t *active_stage;debug_log (DBG_PROCS ,"Enter %s\n" , __func__);
@@ -790,7 +754,6 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) tape->active_data_rq =NULL ; tape->nr_pending_stages--;if (rq->cmd[0 ] &REQ_IDETAPE_WRITE ) { - remove_stage =1 ;if (error) {set_bit (IDETAPE_FLAG_PIPELINE_ERR , &tape->flags);
@@ -831,8 +794,6 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) }ide_end_drive_cmd (drive,0 ,0 ); -if (remove_stage) -idetape_remove_stage_head (drive);if (tape->active_data_rq ==NULL )clear_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags);spin_unlock_irqrestore (&tape->lock, flags);
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 07/17] ide-tape: remove idetape_remove_stage_head()
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 8/17 ide-tape: remove pipeline-specific code from idetape_end_request()
In reply to Borislav PetkovAs a side effect, remove unused idetape_kfree_stage() and idetape_abort_pipeline()
--- drivers/ide/ide-tape.c | 83 ------------------------------------------------ 1 files changed, 0 insertions(+), 83 deletions(-)
drivers/ide/ide-tape.c +0 -83
@@ -686,37 +686,6 @@ static void __idetape_kfree_stage(idetape_stage_t *stage)kfree (stage); } -static void idetape_kfree_stage (idetape_tape_t *tape,idetape_stage_t *stage) -{ -__idetape_kfree_stage (stage); -} - -/* -* This will free all the pipeline stages starting from new_last_stage->next -* to the end of the list, and point tape->last_stage to new_last_stage. -*/ -static void idetape_abort_pipeline (ide_drive_t *drive, -idetape_stage_t *new_last_stage) -{ -idetape_tape_t *tape = drive->driver_data; -idetape_stage_t *stage = new_last_stage->next; -idetape_stage_t *nstage; - -debug_log (DBG_PROCS ,"%s: Enter %s\n" , tape->name, __func__); - -while (stage) { - nstage = stage->next; -idetape_kfree_stage (tape, stage); - --tape->nr_stages; - --tape->nr_pending_stages; - stage = nstage; - } -if (new_last_stage) - new_last_stage->next =NULL ; - tape->last_stage = new_last_stage; - tape->next_stage =NULL ; -} -/* * Finish servicing a request and insert a pending pipeline request into the * main device queue.
@@ -725,9 +694,7 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) {struct request *rq =HWGROUP (drive)->rq;idetape_tape_t *tape = drive->driver_data; -unsigned long flags;int error; -idetape_stage_t *active_stage;debug_log (DBG_PROCS ,"Enter %s\n" , __func__);
@@ -745,58 +712,8 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)return 0 ; } -spin_lock_irqsave (&tape->lock, flags); - -/* The request was a pipelined data transfer request */ -if (tape->active_data_rq == rq) { - active_stage = tape->active_stage; - tape->active_stage =NULL ; - tape->active_data_rq =NULL ; - tape->nr_pending_stages--; -if (rq->cmd[0 ] &REQ_IDETAPE_WRITE ) { -if (error) { -set_bit (IDETAPE_FLAG_PIPELINE_ERR , - &tape->flags); -if (error ==IDETAPE_ERROR_EOD ) -idetape_abort_pipeline (drive, - active_stage); - } - }else if (rq->cmd[0 ] &REQ_IDETAPE_READ ) { -if (error ==IDETAPE_ERROR_EOD ) { -set_bit (IDETAPE_FLAG_PIPELINE_ERR , - &tape->flags); -idetape_abort_pipeline (drive, active_stage); - } - } -if (tape->next_stage !=NULL ) { -idetape_activate_next_stage (drive); - -/* Insert the next request into the request queue. */ - (void )ide_do_drive_cmd (drive, tape->active_data_rq, - ide_end); - }else if (!error) { -/* -* This is a part of the feedback loop which tries to -* find the optimum number of stages. We are starting -* from a minimum maximum number of stages, and if we -* sense that the pipeline is empty, we try to increase -* it, until we reach the user compile time memory -* limit. -*/ -int i = (tape->max_pipeline - tape->min_pipeline) /10 ; - - tape->max_stages +=max (i,1 ); - tape->max_stages =max (tape->max_stages, - tape->min_pipeline); - tape->max_stages =min (tape->max_stages, - tape->max_pipeline); - } - }ide_end_drive_cmd (drive,0 ,0 ); -if (tape->active_data_rq ==NULL ) -clear_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags); -spin_unlock_irqrestore (&tape->lock, flags);return 0 ; }
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 08/17] ide-tape: remove pipeline-specific code from idetape_end_request()
Quoted 4 lines · Borislav Petkov
As a side effect, remove unused
idetape_kfree_stage()andidetape_abort_pipeline()Signed-off-by Borislav Petkov <[email protected]>
applied
[ I resurrected taking tape->lock + clearing IDETAPE_FLAG_PIPELINE_ACTIVE ]
PATCH 9/17 ide-tape: unwrap idetape_queue_pc_tail()
In reply to Borislav Petkovidetape_queue_pc_tail() is a wrapper for its __idetape_queue_pc_tail() counterpart and has no other functionality. Remove it and call the "wrapped" function directly.
--- drivers/ide/ide-tape.c | 11 +++-------- 1 files changed, 3 insertions(+), 8 deletions(-)
drivers/ide/ide-tape.c +3 -8
@@ -1631,7 +1631,7 @@ static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)* to the request list without waiting for it to be serviced! In that case, we * usually use idetape_queue_pc_head(). */ -static int __idetape_queue_pc_tail (ide_drive_t *drive,struct ide_atapi_pc *pc) +static int idetape_queue_pc_tail (ide_drive_t *drive,struct ide_atapi_pc *pc) {struct ide_tape_obj *tape = drive->driver_data;struct request rq;
@@ -1663,7 +1663,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) timeout += jiffies;while (time_before (jiffies, timeout)) {idetape_create_test_unit_ready_cmd (&pc); -if (!__idetape_queue_pc_tail (drive, &pc)) +if (!idetape_queue_pc_tail (drive, &pc))return 0 ;if ((tape->sense_key ==2 && tape->asc ==4 && tape->ascq ==2 ) || (tape->asc ==0x3A )) {
@@ -1672,7 +1672,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)return -ENOMEDIUM ;idetape_create_load_unload_cmd (drive, &pc,IDETAPE_LU_LOAD_MASK ); -__idetape_queue_pc_tail (drive, &pc); +idetape_queue_pc_tail (drive, &pc); load_attempted =1 ;/* not about to be ready */ } else if (!(tape->sense_key == 2 && tape->asc == 4 &&
@@ -1683,11 +1683,6 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)return -EIO ; } -static int idetape_queue_pc_tail (ide_drive_t *drive,struct ide_atapi_pc *pc) -{ -return __idetape_queue_pc_tail (drive, pc); -} -static int idetape_flush_tape_buffers (ide_drive_t *drive) {struct ide_atapi_pc pc;
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 09/17] ide-tape: unwrap idetape_queue_pc_tail()
Quoted 5 lines · Borislav Petkov
idetape_queue_pc_tail()is a wrapper for its__idetape_queue_pc_tail()counterpart and has no other functionality. Remove it and call the "wrapped" function directly.Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 10/17 ide-tape: remove remaining pipeline functionality
In reply to Borislav PetkovThe driver is using now solely its own request queue.
--- drivers/ide/ide-tape.c | 103 +----------------------------------------------- 1 files changed, 2 insertions(+), 101 deletions(-)
drivers/ide/ide-tape.c +2 -101
@@ -642,28 +642,6 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) } } -static void idetape_activate_next_stage (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -idetape_stage_t *stage = tape->next_stage; -struct request *rq = &stage->rq; - -debug_log (DBG_PROCS ,"Enter %s\n" , __func__); - -if (stage ==NULL ) { -printk (KERN_ERR "ide-tape: bug: Trying to activate a non" -" existing stage\n" ); -return ; - } - - rq->rq_disk = tape->disk; - rq->buffer =NULL ; - rq->special = (void *)stage->bh; - tape->active_data_rq = rq; - tape->active_stage = stage; - tape->next_stage = stage->next; -} -/* Free a stage along with its related buffers completely. */ static void __idetape_kfree_stage (idetape_stage_t *stage) {
@@ -1541,28 +1519,6 @@ static void idetape_init_merge_stage(idetape_tape_t *tape) } } -/* Install a completion in a pending request and sleep until it is serviced. The -* caller should ensure that the request will not be serviced before we install -* the completion (usually by disabling interrupts). -*/ -static void idetape_wait_for_request (ide_drive_t *drive,struct request *rq) -{ -DECLARE_COMPLETION_ONSTACK (wait); -idetape_tape_t *tape = drive->driver_data; - -if (rq ==NULL || !blk_special_request (rq)) { -printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid" -" request\n" ); -return ; - } - rq->end_io_data = &wait; - rq->end_io = blk_end_sync_rq; -spin_unlock_irq (&tape->lock); -wait_for_completion (&wait); -/* The stage and its struct request have been deallocated */ -spin_lock_irq (&tape->lock); -} -static ide_startstop_t idetape_read_position_callback (ide_drive_t *drive) {idetape_tape_t *tape = drive->driver_data;
@@ -1806,19 +1762,6 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,return (tape->blk_size * (blocks-rq.current_nr_sectors)); } -/* start servicing the pipeline stages, starting from tape->next_stage. */ -static void idetape_plug_pipeline (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; - -if (tape->next_stage ==NULL ) -return ; -if (!test_and_set_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) { -idetape_activate_next_stage (drive); - (void )ide_do_drive_cmd (drive, tape->active_data_rq, ide_end); - } -} -static void idetape_create_inquiry_cmd (struct ide_atapi_pc *pc) {idetape_init_pc (pc);
@@ -1860,45 +1803,11 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)static int idetape_add_chrdev_write_request (ide_drive_t *drive,int blocks) {idetape_tape_t *tape = drive->driver_data; -unsigned long flags;debug_log (DBG_CHRDEV ,"Enter %s\n" , __func__); -/* Attempt to allocate a new stage. Beware possible race conditions. */ -while (1 ) { -spin_lock_irqsave (&tape->lock, flags); -if (test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) { -idetape_wait_for_request (drive, tape->active_data_rq); -spin_unlock_irqrestore (&tape->lock, flags); - }else { -spin_unlock_irqrestore (&tape->lock, flags); -idetape_plug_pipeline (drive); -if (test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , - &tape->flags)) -continue ; -return idetape_queue_rw_tail (drive,REQ_IDETAPE_WRITE , - blocks, tape->merge_stage->bh); - } - } -} - -/* -* Wait until all pending pipeline requests are serviced. Typically called on -* device close. -*/ -static void idetape_wait_for_pipeline (ide_drive_t *drive) -{ -idetape_tape_t *tape = drive->driver_data; -unsigned long flags; - -while (tape->next_stage ||test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , - &tape->flags)) { -idetape_plug_pipeline (drive); -spin_lock_irqsave (&tape->lock, flags); -if (test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) -idetape_wait_for_request (drive, tape->active_data_rq); -spin_unlock_irqrestore (&tape->lock, flags); - } +return idetape_queue_rw_tail (drive,REQ_IDETAPE_WRITE , + blocks, tape->merge_stage->bh); }static int idetape_init_read (ide_drive_t *drive,int max_stages)
@@ -1909,7 +1818,6 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages)/* Initialize read operation */ if (tape->chrdev_dir !=IDETAPE_DIR_READ ) {if (tape->chrdev_dir ==IDETAPE_DIR_WRITE ) { -idetape_wait_for_pipeline (drive);idetape_flush_tape_buffers (drive); }if (tape->merge_stage || tape->merge_stage_size) {
@@ -1947,7 +1855,6 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages) tape->insert_time = jiffies; tape->insert_size =0 ; tape->insert_speed =0 ; -idetape_plug_pipeline (drive); } }return 0 ;
@@ -2428,7 +2335,6 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,debug_log (DBG_CHRDEV ,"Enter %s, cmd=%u\n" , __func__, cmd);if (tape->chrdev_dir ==IDETAPE_DIR_WRITE ) { -idetape_wait_for_pipeline (drive);idetape_flush_tape_buffers (drive); }if (cmd ==MTIOCGET || cmd ==MTIOCPOS ) {
@@ -2578,7 +2484,6 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) {idetape_tape_t *tape = drive->driver_data; -idetape_wait_for_pipeline (drive); tape->merge_stage =__idetape_kmalloc_stage (tape,1 ,0 );if (tape->merge_stage !=NULL ) { idetape_pad_zeros(drive, tape->blk_size *
@@ -2605,10 +2510,6 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)if (tape->chrdev_dir ==IDETAPE_DIR_WRITE )idetape_write_release (drive, minor); -if (tape->chrdev_dir ==IDETAPE_DIR_READ ) { -if (minor >=128 ) -idetape_wait_for_pipeline (drive); - }if (minor <128 &&test_bit (IDETAPE_FLAG_MEDIUM_PRESENT , &tape->flags)) (void )idetape_rewind_tape (drive);
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 10/17] ide-tape: remove remaining pipeline functionality
Quoted 1 line · Borislav Petkov
The driver is using now solely its own request queue.
patch summary and patch description are _very_ sparse
[ at least two things are worth mentioning here:
- tape->next_stage is always NULL so it is safe to remove
all code depending on tape->next_stage != NULL
- this patch removes the last place which sets
IDETAPE_FLAG_PIPELINE_ACTIVE in tape->flags ]
Quoted 1 line
Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 11/17 ide-tape: remove pipeline-specific code from idetape_setup
In reply to Borislav Petkov--- drivers/ide/ide-tape.c | 40 ++++------------------------------------ 1 files changed, 4 insertions(+), 36 deletions(-)
drivers/ide/ide-tape.c +4 -36
@@ -2690,11 +2690,10 @@ static inline void idetape_add_settings(ide_drive_t *drive) { ; }*/ static void idetape_setup (ide_drive_t *drive,idetape_tape_t *tape,int minor) { -unsigned long t1, tmid, tn, t; +unsigned long t;int speed;int stage_size;u8 gcw[2 ]; -struct sysinfo si;u16 *ctl = (u16 *)&tape->caps[12 ];spin_lock_init (&tape->lock);
@@ -2719,10 +2718,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)if (((gcw[0 ] &0x60 ) >>5 ) ==1 )set_bit (IDETAPE_FLAG_DRQ_INTERRUPT , &tape->flags); - tape->min_pipeline =10 ; - tape->max_pipeline =10 ; - tape->max_stages =10 ; -idetape_get_inquiry_results (drive);idetape_get_mode_sense_results (drive);ide_tape_get_bsize_from_bdesc (drive);
@@ -2740,36 +2735,10 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) tape->excess_bh_size =PAGE_SIZE - stage_size %PAGE_SIZE ; } -/* Select the "best" DSC read/write polling freq and pipeline size. */ +/* select the "best" DSC read/write polling freq */ speed =max (*(u16 *)&tape->caps[14 ], *(u16 *)&tape->caps[8 ]); - tape->max_stages = speed *1000 *10 / tape->stage_size; - -/* Limit memory use for pipeline to 10% of physical memory */ -si_meminfo (&si); -if (tape->max_stages * tape->stage_size > - si.totalram * si.mem_unit /10 ) - tape->max_stages = - si.totalram * si.mem_unit / (10 * tape->stage_size); - - tape->max_stages =min (tape->max_stages,IDETAPE_MAX_PIPELINE_STAGES ); - tape->min_pipeline =min (tape->max_stages,IDETAPE_MIN_PIPELINE_STAGES ); - tape->max_pipeline = -min (tape->max_stages *2 ,IDETAPE_MAX_PIPELINE_STAGES ); -if (tape->max_stages ==0 ) { - tape->max_stages =1 ; - tape->min_pipeline =1 ; - tape->max_pipeline =1 ; - } - - t1 = (tape->stage_size *HZ ) / (speed *1000 ); - tmid = (*(u16 *)&tape->caps[16 ] *32 *HZ ) / (speed *125 ); - tn = (IDETAPE_FIFO_THRESHOLD * tape->stage_size *HZ ) / (speed *1000 ); - -if (tape->max_stages) - t = tn; -else - t = t1; + t = (tape->stage_size *HZ ) / (speed *1000 );/* * Ensure that the number we got makes sense; limit it within
@@ -2779,11 +2748,10 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) min_t(unsigned long, t, IDETAPE_DSC_RW_MAX), IDETAPE_DSC_RW_MIN);printk (KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " -"%dkB pipeline, %lums tDSC%s\n" , +"%lums tDSC%s\n" , drive->name, tape->name, *(u16 *)&tape->caps[14 ], (*(u16 *)&tape->caps[16 ] *512 ) / tape->stage_size, tape->stage_size /1024 , - tape->max_stages * tape->stage_size /1024 , tape->best_dsc_rw_freq *1000 /HZ , drive->using_dma ?", DMA" :"" );
Signature · 1 line
1.5.4.1
Re: [PATCH 11/17] ide-tape: remove pipeline-specific code from idetape_setup
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
->max_stages and ->{min,max}_pipeline are later removed in patch #14, it makes sense to merge both patches together [ as I did ;-) ]
[...]
Quoted 5 lines
drivers/ide/ide-tape.c +0
-5-if (tape->max_stages ==0 ) { - tape->max_stages =1 ; - tape->min_pipeline =1 ; - tape->max_pipeline =1 ; - }
drivers/ide/ide-tape.c static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) · line 2741
Quoted 10 lines
drivers/ide/ide-tape.c +1
-9- - t1 = (tape->stage_size *HZ ) / (speed *1000 ); - tmid = (*(u16 *)&tape->caps[16 ] *32 *HZ ) / (speed *125 ); - tn = (IDETAPE_FIFO_THRESHOLD * tape->stage_size *HZ ) / (speed *1000 ); - -if (tape->max_stages) - t = tn; -else - t = t1; + t = (tape->stage_size *HZ ) / (speed *1000 );
tape->max_stages was always > 0 so 't' should use 'tn' not 't1' (fixed during merge)
PATCH 12/17 ide-tape: remove pipelined mode parameters
In reply to Borislav Petkov--- drivers/ide/ide-tape.c | 17 ----------------- 1 files changed, 0 insertions(+), 17 deletions(-)
drivers/ide/ide-tape.c +0 -17
@@ -72,23 +72,6 @@ enum {#endif /**************************** Tunable parameters *****************************/ - - -/* -* Pipelined mode parameters. -* -* We try to use the minimum number of stages which is enough to keep the tape -* constantly streaming. To accomplish that, we implement a feedback loop around -* the maximum number of stages: -* -* We start from MIN maximum stages (we will not even use MIN stages if we don't -* need them), increment it by RATE*(MAX-MIN) whenever we sense that the -* pipeline is empty, until we reach the optimum value or until we reach MAX. -*/ -#define IDETAPE_MIN_PIPELINE_STAGES 1 -#define IDETAPE_MAX_PIPELINE_STAGES 400 -#define IDETAPE_INCREASE_STAGES_RATE 20 -/* * After each failed packet command we issue a request sense command and retry * the packet command IDETAPE_MAX_PC_RETRIES times.
Signature · 1 line
1.5.4.1
Re: [PATCH 12/17] ide-tape: remove pipelined mode parameters
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied (after patch #14)
PATCH 13/17 ide-tape: remove pipelined mode tape control flags
In reply to Borislav Petkov--- drivers/ide/ide-tape.c | 34 +++++----------------------------- 1 files changed, 5 insertions(+), 29 deletions(-)
drivers/ide/ide-tape.c +5 -29
@@ -204,19 +204,15 @@ enum {/* 0 When the tape position is unknown */ IDETAPE_FLAG_ADDRESS_VALID = (1 <<1 ),/* Device already opened */ -IDETAPE_FLAG_BUSY = (1 <<2 ), -/* Error detected in a pipeline stage */ -IDETAPE_FLAG_PIPELINE_ERR = (1 <<3 ), +IDETAPE_FLAG_BUSY = (1 <<2 ),/* Attempt to auto-detect the current user block size */ -IDETAPE_FLAG_DETECT_BS = (1 <<4 ), +IDETAPE_FLAG_DETECT_BS = (1 <<3 ),/* Currently on a filemark */ -IDETAPE_FLAG_FILEMARK = (1 <<5 ), +IDETAPE_FLAG_FILEMARK = (1 <<4 ),/* DRQ interrupt device */ -IDETAPE_FLAG_DRQ_INTERRUPT = (1 <<6 ), -/* pipeline active */ -IDETAPE_FLAG_PIPELINE_ACTIVE = (1 <<7 ), +IDETAPE_FLAG_DRQ_INTERRUPT = (1 <<5 ),/* 0 = no tape is loaded, so we don't rewind after ejecting */ - IDETAPE_FLAG_MEDIUM_PRESENT = (1 << 8), + IDETAPE_FLAG_MEDIUM_PRESENT = (1 << 6), };/* A pipeline stage. */
@@ -1721,12 +1717,6 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,debug_log (DBG_SENSE ,"%s: cmd=%d\n" , __func__, cmd); -if (test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) { -printk (KERN_ERR "ide-tape: bug: the pipeline is active in %s\n" , - __func__); -return (0 ); - } -idetape_init_rq (&rq, cmd); rq.rq_disk = tape->disk; rq.special = (void *)bh;
@@ -1832,14 +1822,6 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages) } } -if (!test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) { -if (tape->nr_pending_stages >=3 * max_stages /4 ) { - tape->measure_insert_time =1 ; - tape->insert_time = jiffies; - tape->insert_size =0 ; - tape->insert_speed =0 ; - } - }return 0 ; }
@@ -1859,9 +1841,6 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)idetape_init_read (drive, tape->max_stages); -if (test_bit (IDETAPE_FLAG_PIPELINE_ERR , &tape->flags)) -return 0 ; -return idetape_queue_rw_tail (drive,REQ_IDETAPE_READ , blocks, tape->merge_stage->bh); }
@@ -2425,9 +2404,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)if (!test_bit (IDETAPE_FLAG_ADDRESS_VALID , &tape->flags)) (void )idetape_rewind_tape (drive); -if (tape->chrdev_dir !=IDETAPE_DIR_READ ) -clear_bit (IDETAPE_FLAG_PIPELINE_ERR , &tape->flags); -/* Read block size and write protect status from drive. */ ide_tape_get_bsize_from_bdesc (drive);
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 13/17] ide-tape: remove pipelined mode tape control flags
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied
drivers/ide/ide-tape.c static int idetape_init_read(ide_drive_t *drive, int max_stages) · line 1842
Quoted 12 lines
drivers/ide/ide-tape.c +0
-8@@ -1832,14 +1822,6 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages) } } -if (!test_bit (IDETAPE_FLAG_PIPELINE_ACTIVE , &tape->flags)) { -if (tape->nr_pending_stages >=3 * max_stages /4 ) { - tape->measure_insert_time =1 ; - tape->insert_time = jiffies; - tape->insert_size =0 ; - tape->insert_speed =0 ; - } - }
It is !test_bit() so the second 'if ()' block should be preserved (I fixed this while merging the patch).
PATCH 14/17 ide-tape: remove pipeline-specific members from struct ide_tape_obj
In reply to Borislav Petkov--- drivers/ide/ide-tape.c | 79 ++++------------------------------------------- 1 files changed, 7 insertions(+), 72 deletions(-)
drivers/ide/ide-tape.c +7 -72
@@ -307,12 +307,8 @@ typedef struct ide_tape_obj {* At most, there is only one ide-tape originated data transfer request * in the device request queue. This allows ide.c to easily service * requests from the other device when we postpone our active request. -* In the pipelined operation mode, we use our internal pipeline -* structure to hold more data requests. The data buffer size is chosen -* based on the tape's recommendation. */ -/* ptr to the request which is waiting in the device request queue */ -struct request *active_data_rq; +/* Data buffer size chosen based on the tape's recommendation */ int stage_size;idetape_stage_t *merge_stage;
@@ -321,26 +317,7 @@ typedef struct ide_tape_obj {char *b_data;int b_count; -/* -* Pipeline parameters. -* -* To accomplish non-pipelined mode, we simply set the following -* variables to zero (or NULL, where appropriate). -*/ -/* Number of currently used stages */ -int nr_stages; -/* Number of pending stages */ -int nr_pending_stages; -/* We will not allocate more than this number of stages */ -int max_stages, min_pipeline, max_pipeline; -/* The first stage which will be removed from the pipeline */ -idetape_stage_t *first_stage; -/* The currently active stage */ -idetape_stage_t *active_stage; -/* Will be serviced after the currently active request */ -idetape_stage_t *next_stage; -/* New requests will be added to the pipeline here */ -idetape_stage_t *last_stage; +/* Pipeline parameters. */ int pages_per_stage;/* Wasted space in each stage */ int excess_bh_size;
@@ -362,18 +339,6 @@ typedef struct ide_tape_obj {/* the tape is write protected (hardware or opened as read-only) */ char write_prot; -/* -* Limit the number of times a request can be postponed, to avoid an -* infinite postpone deadlock. -*/ -int postpone_cnt; - -/* Speed control at the tape buffers input/output */ -unsigned long insert_time; -int insert_size; -int insert_speed; -int measure_insert_time; -u32 debug_mask; } idetape_tape_t;
@@ -1172,17 +1137,7 @@ static ide_startstop_t idetape_rw_callback(ide_drive_t *drive)int blocks = tape->pc->xferred / tape->blk_size; tape->avg_size += blocks * tape->blk_size; - tape->insert_size += blocks * tape->blk_size; -if (tape->insert_size >1024 *1024 ) - tape->measure_insert_time =1 ; -if (tape->measure_insert_time) { - tape->measure_insert_time =0 ; - tape->insert_time = jiffies; - tape->insert_size =0 ; - } -if (time_after (jiffies, tape->insert_time)) - tape->insert_speed = tape->insert_size /1024 *HZ / - (jiffies - tape->insert_time); +if (time_after_eq (jiffies, tape->avg_time +HZ )) { tape->avg_speed = tape->avg_size *HZ / (jiffies - tape->avg_time) /1024 ;
@@ -1287,9 +1242,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, drive->post_reset =0 ; } -if (time_after (jiffies, tape->insert_time)) - tape->insert_speed = tape->insert_size /1024 *HZ / - (jiffies - tape->insert_time);if (!test_and_clear_bit (IDETAPE_FLAG_IGNORE_DSC , &tape->flags) && (stat &SEEK_STAT ) ==0 ) {if (postponed_rq ==NULL ) {
@@ -1313,14 +1265,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,return ide_stopped; }if (rq->cmd[0 ] &REQ_IDETAPE_READ ) { - tape->postpone_cnt =0 ; pc =idetape_next_pc_storage (drive);idetape_create_read_cmd (tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); goto out; }if (rq->cmd[0 ] &REQ_IDETAPE_WRITE ) { - tape->postpone_cnt =0 ; pc =idetape_next_pc_storage (drive);idetape_create_write_cmd (tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
@@ -1783,7 +1733,7 @@ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) blocks, tape->merge_stage->bh); } -static int idetape_init_read (ide_drive_t *drive,int max_stages) +static int idetape_init_read (ide_drive_t *drive) {idetape_tape_t *tape = drive->driver_data;int bytes_read;
@@ -1839,7 +1789,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)if (test_bit (IDETAPE_FLAG_FILEMARK , &tape->flags))return 0 ; -idetape_init_read (drive, tape->max_stages); +idetape_init_read (drive);return idetape_queue_rw_tail (drive,REQ_IDETAPE_READ , blocks, tape->merge_stage->bh);
@@ -1905,7 +1855,6 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,struct idetape_config {int dsc_rw_frequency;int dsc_media_access_frequency; -int nr_stages; } config;debug_log (DBG_PROCS ,"Enter %s\n" , __func__);
@@ -1915,11 +1864,9 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,if (copy_from_user (&config, argp,sizeof (config)))return -EFAULT ; tape->best_dsc_rw_freq = config.dsc_rw_frequency; - tape->max_stages = config.nr_stages;break ;case 0x0350 : config.dsc_rw_frequency = (int ) tape->best_dsc_rw_freq; - config.nr_stages = tape->max_stages;if (copy_to_user (argp, &config,sizeof (config)))return -EFAULT ;break ;
@@ -2006,7 +1953,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, (count % tape->blk_size) == 0) tape->user_bs_factor = count / tape->blk_size; } - rc =idetape_init_read (drive, tape->max_stages); + rc =idetape_init_read (drive);if (rc <0 )return rc;if (count ==0 )
@@ -2606,18 +2553,6 @@ static void idetape_add_settings(ide_drive_t *drive)ide_add_setting (drive,"buffer" ,SETTING_READ ,TYPE_SHORT ,0 ,0xffff ,1 ,2 , (u16 *)&tape->caps[16 ],NULL ); -ide_add_setting (drive,"pipeline_min" ,SETTING_RW ,TYPE_INT ,1 ,0xffff , - tape->stage_size /1024 ,1 , &tape->min_pipeline,NULL ); -ide_add_setting (drive,"pipeline" ,SETTING_RW ,TYPE_INT ,1 ,0xffff , - tape->stage_size /1024 ,1 , &tape->max_stages,NULL ); -ide_add_setting (drive,"pipeline_max" ,SETTING_RW ,TYPE_INT ,1 ,0xffff , - tape->stage_size /1024 ,1 , &tape->max_pipeline,NULL ); -ide_add_setting (drive,"pipeline_used" ,SETTING_READ ,TYPE_INT ,0 , -0xffff , tape->stage_size /1024 ,1 , &tape->nr_stages, -NULL ); -ide_add_setting (drive,"pipeline_pending" ,SETTING_READ ,TYPE_INT ,0 , -0xffff , tape->stage_size /1024 ,1 , - &tape->nr_pending_stages,NULL );ide_add_setting (drive,"speed" ,SETTING_READ ,TYPE_SHORT ,0 ,0xffff ,1 ,1 , (u16 *)&tape->caps[14 ],NULL ); ide_add_setting(drive, "stage", SETTING_READ, TYPE_INT, 0, 0xffff, 1,
@@ -2734,7 +2669,7 @@ static void ide_tape_release(struct kref *kref)ide_drive_t *drive = tape->drive;struct gendisk *g = tape->disk; -BUG_ON (tape->first_stage !=NULL || tape->merge_stage_size); +BUG_ON (tape->merge_stage_size); drive->dsc_overlap =0 ; drive->driver_data =NULL ;
Signature · 1 line
1.5.4.1
Re: [PATCH 14/17] ide-tape: remove pipeline-specific members from struct ide_tape_obj
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied after:
- merging with "ide-tape: remove pipeline-specific code from idetape_setup"
- cleaning up __idetape_discard_read_pipeline() (since patch #3 was dropped)
- cleaning up idetape_empty_write_pipeline() (since patch #4 was dropped)
drivers/ide/ide-tape.c static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, · line 1908
Quoted 5 lines
drivers/ide/ide-tape.c +0
-1@@ -1905,7 +1855,6 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,struct idetape_config {int dsc_rw_frequency;int dsc_media_access_frequency; -int nr_stages;
we need to keep it:
drivers/ide/ide-tape.c static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, · line 1922
Quoted 12 lines
drivers/ide/ide-tape.c +0
-2} config;debug_log (DBG_PROCS ,"Enter %s\n" , __func__);@@ -1915,11 +1864,9 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,if (copy_from_user (&config, argp,sizeof (config)))return -EFAULT ; tape->best_dsc_rw_freq = config.dsc_rw_frequency; - tape->max_stages = config.nr_stages;break ;case 0x0350 : config.dsc_rw_frequency = (int ) tape->best_dsc_rw_freq; - config.nr_stages = tape->max_stages;
changed this to export '1' to user-space (which has always meant that pipeline-mode is disabled)
Quoted 3 lines
drivers/ide/ide-tape.c +0
-0if (copy_to_user (argp, &config,sizeof (config)))return -EFAULT ;break ;
PATCH 15/17 ide-tape: remove misc references to pipelined operation in the comments
In reply to Borislav Petkov--- drivers/ide/ide-tape.c | 22 +++------------------- 1 files changed, 3 insertions(+), 19 deletions(-)
drivers/ide/ide-tape.c +3 -19
@@ -265,9 +265,7 @@ typedef struct ide_tape_obj {* While polling for DSC we use postponed_rq to postpone the current * request so that ide.c will be able to service pending requests on the * other device. Note that at most we will have only one DSC (usually -* data transfer) request in the device request queue. Additional -* requests can be queued in our internal pipeline, but they will be -* visible to ide.c only one at a time. +* data transfer) request in the device request queue. */ struct request *postponed_rq;/* The time in which we started polling for DSC */
@@ -608,10 +606,6 @@ static void __idetape_kfree_stage(idetape_stage_t *stage)kfree (stage); } -/* -* Finish servicing a request and insert a pending pipeline request into the -* main device queue. -*/ static int idetape_end_request (ide_drive_t *drive,int uptodate,int nr_sects) {struct request *rq =HWGROUP (drive)->rq;
@@ -1291,8 +1285,6 @@ out:return idetape_issue_pc (drive, pc); } -/* Pipeline related functions */ -/* * The function below uses __get_free_page to allocate a pipeline stage, along * with all the necessary small buffers which together make a buffer of size
@@ -1301,9 +1293,6 @@ out:* * It returns a pointer to the new allocated stage, or NULL if we can't (or * don't want to) allocate a stage. -* -* Pipeline stages are optional and are used to increase performance. If we -* can't allocate them, we'll manage without them. */ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape,int full,int clear)
@@ -1775,10 +1764,7 @@ static int idetape_init_read(ide_drive_t *drive)return 0 ; } -/* -* Called from idetape_chrdev_read() to service a character device read request -* and add read-ahead requests to our pipeline. -*/ +/* called from idetape_chrdev_read() to service a chrdev read request. */ static int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks) {idetape_tape_t *tape = drive->driver_data;
@@ -2107,8 +2093,7 @@ static int idetape_write_filemark(ide_drive_t *drive)* * Note: MTBSF and MTBSFM are not supported when the tape doesn't support * spacing over filemarks in the reverse direction. In this case, MTFSFM is also -* usually not supported (it is supported in the rare case in which we crossed -* the filemark during our read-ahead pipelined operation mode). +* usually not supported. * * The following commands are currently not supported: *
@@ -2124,7 +2109,6 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)debug_log (DBG_ERR ,"Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n" , mt_op, mt_count); -/* Commands which need our pipelined read-ahead stages. */ switch (mt_op) {case MTFSF :case MTFSFM :
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 15/17] ide-tape: remove misc references to pipelined operation in the comments
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 16/17 ide-tape: remove pipelined mode description from Documentation/ide/ide-tape.txt
In reply to Borislav Petkov--- Documentation/ide/ide-tape.txt | 79 ---------------------------------------- 1 files changed, 0 insertions(+), 79 deletions(-)
Documentation/ide/ide-tape.txt +0 -79
@@ -8,8 +8,6 @@ * interface, on the other hand, creates new requests, adds them * to the request-list of the block device, and waits for their completion. * - * Pipelined operation mode is now supported on both reads and writes. - * * The block device major and minor numbers are determined from the * tape's relative position in the ide interfaces, as explained in ide.c. *
@@ -45,83 +43,6 @@ * * | Special care is recommended. Have Fun! * - * - * An overview of the pipelined operation mode. - * - * In the pipelined write mode, we will usually just add requests to our - * pipeline and return immediately, before we even start to service them. The - * user program will then have enough time to prepare the next request while - * we are still busy servicing previous requests. In the pipelined read mode, - * the situation is similar - we add read-ahead requests into the pipeline, - * before the user even requested them. - * - * The pipeline can be viewed as a "safety net" which will be activated when - * the system load is high and prevents the user backup program from keeping up - * with the current tape speed. At this point, the pipeline will get - * shorter and shorter but the tape will still be streaming at the same speed. - * Assuming we have enough pipeline stages, the system load will hopefully - * decrease before the pipeline is completely empty, and the backup program - * will be able to "catch up" and refill the pipeline again. - * - * When using the pipelined mode, it would be best to disable any type of - * buffering done by the user program, as ide-tape already provides all the - * benefits in the kernel, where it can be done in a more efficient way. - * As we will usually not block the user program on a request, the most - * efficient user code will then be a simple read-write-read-... cycle. - * Any additional logic will usually just slow down the backup process. - * - * Using the pipelined mode, I get a constant over 400 KBps throughput, - * which seems to be the maximum throughput supported by my tape. - * - * However, there are some downfalls: - * - * 1. We use memory (for data buffers) in proportional to the number - * of pipeline stages (each stage is about 26 KB with my tape). - * 2. In the pipelined write mode, we cheat and postpone error codes - * to the user task. In read mode, the actual tape position - * will be a bit further than the last requested block. - * - * Concerning (1): - * - * 1. We allocate stages dynamically only when we need them. When - * we don't need them, we don't consume additional memory. In - * case we can't allocate stages, we just manage without them - * (at the expense of decreased throughput) so when Linux is - * tight in memory, we will not pose additional difficulties. - * - * 2. The maximum number of stages (which is, in fact, the maximum - * amount of memory) which we allocate is limited by the compile - * time parameter IDETAPE_MAX_PIPELINE_STAGES. - * - * 3. The maximum number of stages is a controlled parameter - We - * don't start from the user defined maximum number of stages - * but from the lower IDETAPE_MIN_PIPELINE_STAGES (again, we - * will not even allocate this amount of stages if the user - * program can't handle the speed). We then implement a feedback - * loop which checks if the pipeline is empty, and if it is, we - * increase the maximum number of stages as necessary until we - * reach the optimum value which just manages to keep the tape - * busy with minimum allocated memory or until we reach - * IDETAPE_MAX_PIPELINE_STAGES. - * - * Concerning (2): - * - * In pipelined write mode, ide-tape can not return accurate error codes - * to the user program since we usually just add the request to the - * pipeline without waiting for it to be serviced. In case an error - * occurs, I will report it on the next user request. - * - * In the pipelined read mode, subsequent read requests or forward - * filemark spacing will perform correctly, as we preserve all blocks - * and filemarks which we encountered during our excess read-ahead. - * - * For accurate tape positioning and error reporting, disabling - * pipelined mode might be the best option. - * - * You can enable/disable/tune the pipelined operation mode by adjusting - * the compile time parameters below. - * - * * Possible improvements. * * 1. Support for the ATAPI overlap protocol.
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 16/17] ide-tape: remove pipelined mode description from Documentation/ide/ide-tape.txt
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied
PATCH 17/17 ide-tape: remove comments markup from Documentation/ide/ide-tape.txt
In reply to Borislav Petkov--- Documentation/ide/ide-tape.txt | 132 ++++++++++++++++++++-------------------- 1 files changed, 65 insertions(+), 67 deletions(-)
Documentation/ide/ide-tape.txt +65 -67
@@ -1,67 +1,65 @@ -/* - * IDE ATAPI streaming tape driver. - * - * This driver is a part of the Linux ide driver. - * - * The driver, in co-operation with ide.c, basically traverses the - * request-list for the block device interface. The character device - * interface, on the other hand, creates new requests, adds them - * to the request-list of the block device, and waits for their completion. - * - * The block device major and minor numbers are determined from the - * tape's relative position in the ide interfaces, as explained in ide.c. - * - * The character device interface consists of the following devices: - * - * ht0 major 37, minor 0 first IDE tape, rewind on close. - * ht1 major 37, minor 1 second IDE tape, rewind on close. - * ... - * nht0 major 37, minor 128 first IDE tape, no rewind on close. - * nht1 major 37, minor 129 second IDE tape, no rewind on close. - * ... - * - * The general magnetic tape commands compatible interface, as defined by - * include/linux/mtio.h, is accessible through the character device. - * - * General ide driver configuration options, such as the interrupt-unmask - * flag, can be configured by issuing an ioctl to the block device interface, - * as any other ide device. - * - * Our own ide-tape ioctl's can be issued to either the block device or - * the character device interface. - * - * Maximal throughput with minimal bus load will usually be achieved in the - * following scenario: - * - * 1. ide-tape is operating in the pipelined operation mode. - * 2. No buffering is performed by the user backup program. - * - * Testing was done with a 2 GB CONNER CTMA 4000 IDE ATAPI Streaming Tape Drive. - * - * Here are some words from the first releases of hd.c, which are quoted - * in ide.c and apply here as well: - * - * | Special care is recommended. Have Fun! - * - * Possible improvements. - * - * 1. Support for the ATAPI overlap protocol. - * - * In order to maximize bus throughput, we currently use the DSC - * overlap method which enables ide.c to service requests from the - * other device while the tape is busy executing a command. The - * DSC overlap method involves polling the tape's status register - * for the DSC bit, and servicing the other device while the tape - * isn't ready. - * - * In the current QIC development standard (December 1995), - * it is recommended that new tape drives will *in addition* - * implement the ATAPI overlap protocol, which is used for the - * same purpose - efficient use of the IDE bus, but is interrupt - * driven and thus has much less CPU overhead. - * - * ATAPI overlap is likely to be supported in most new ATAPI - * devices, including new ATAPI cdroms, and thus provides us - * a method by which we can achieve higher throughput when - * sharing a (fast) ATA-2 disk with any (slow) new ATAPI device. - */ +IDE ATAPI streaming tape driver. + +This driver is a part of the Linux ide driver. + +The driver, in co-operation with ide.c, basically traverses the +request-list for the block device interface. The character device +interface, on the other hand, creates new requests, adds them +to the request-list of the block device, and waits for their completion. + +The block device major and minor numbers are determined from the +tape's relative position in the ide interfaces, as explained in ide.c. + +The character device interface consists of the following devices: + +ht0 major 37, minor 0 first IDE tape, rewind on close. +ht1 major 37, minor 1 second IDE tape, rewind on close. +... +nht0 major 37, minor 128 first IDE tape, no rewind on close. +nht1 major 37, minor 129 second IDE tape, no rewind on close. +... + +The general magnetic tape commands compatible interface, as defined by +include/linux/mtio.h, is accessible through the character device. + +General ide driver configuration options, such as the interrupt-unmask +flag, can be configured by issuing an ioctl to the block device interface, +as any other ide device. + +Our own ide-tape ioctl's can be issued to either the block device or +the character device interface. + +Maximal throughput with minimal bus load will usually be achieved in the +following scenario: + + 1. ide-tape is operating in the pipelined operation mode. + 2. No buffering is performed by the user backup program. + +Testing was done with a 2 GB CONNER CTMA 4000 IDE ATAPI Streaming Tape Drive. + +Here are some words from the first releases of hd.c, which are quoted +in ide.c and apply here as well: + +| Special care is recommended. Have Fun! + +Possible improvements: + +1. Support for the ATAPI overlap protocol. + +In order to maximize bus throughput, we currently use the DSC +overlap method which enables ide.c to service requests from the +other device while the tape is busy executing a command. The +DSC overlap method involves polling the tape's status register +for the DSC bit, and servicing the other device while the tape +isn't ready. + +In the current QIC development standard (December 1995), +it is recommended that new tape drives will *in addition* +implement the ATAPI overlap protocol, which is used for the +same purpose - efficient use of the IDE bus, but is interrupt +driven and thus has much less CPU overhead. + +ATAPI overlap is likely to be supported in most new ATAPI +devices, including new ATAPI cdroms, and thus provides us +a method by which we can achieve higher throughput when +sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
Signature · 1 line
1.5.4.1
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH 17/17] ide-tape: remove comments markup from Documentation/ide/ide-tape.txt
Quoted 1 line · Borislav Petkov
Signed-off-by Borislav Petkov <[email protected]>
applied
Bartlomiej Zolnierkiewicz
AppliedHi,
Quoted 10 lines · Borislav Petkov
Hi Bart,
here's the rest of the pipeline removal series. What's left is to rewrite the whole allocation logic around
tape->merge_stageand all the other small buffers so that we can get at least some sanity into the driver before working on it any further :).Documentation/ide/ide-tape.txt | 211 ++++--------- drivers/ide/ide-tape.c | 689 ++-------------------------------------- 2 files changed, 99 insertions(+), 801 deletions(-)
Thanks.
I applied everything except patches #3-4 (as they need to be delayed after tape->merge_state and co. rewrite).
Bart