2.5.30 IDE 113
Quoted 11 lines · Marcin Dalecki
Uz.ytkownik Petr Vandrovec napisa?:
Quoted 5 lines
Hi Marcin,
what synchronizes these accesses to make sure that you do not have
twoide_raw_taskfilerequests on the flight, both using samedrive->srequest? It looks to me like that nothing, so you can overwrite request's contents while somebody else already uses this buffer.I don't think so. The queue lock is synchronizing them.
And then we usually add them just to the front of the queue in question and wait for finishment until the request is done.
How queue lock can synchronize them if we do not hold queue lock for entire duration and setup of request, including drive->srequest setup?
Quoted 7 lines
After all
ide_raw_taskfileonly gets used forREQ_SPECIALrequest types. This does *not* contain normal data request from block IO. As of master slave issues - well we have the data pre allocated per device not per channel! Ifq->request_fnwould properly return the error count instead of void, we could even get rid ot the checking forrq->errorsafter finishment... But well that's entierly different story.
For example do_cmd_ioctl() invokes ide_raw_taskfile, without any locking. Two programs, both issuing HDIO_DRIVE_CMD at same time, will compete over one drive->srequest struct: you'll get same drive->srequest structure submitted twice to blk_insert_request (hm, Jens, will this trigger BUG, or will this just damage request list?).
Petr Vandrovec [email protected]
Quoted 8 lines · Petr Vandrovec
Quoted 7 lines
After all
ide_raw_taskfileonly gets used forREQ_SPECIALrequest types. This does *not* contain normal data request from block IO. As of master slave issues - well we have the data pre allocated per device not per channel! Ifq->request_fnwould properly return the error count instead of void, we could even get rid ot the checking forrq->errorsafter finishment... But well that's entierly different story.
Quoted 5 lines
For example
do_cmd_ioctl()invokeside_raw_taskfile, without any locking. Two programs, both issuingHDIO_DRIVE_CMDat same time, will compete over onedrive->srequeststruct: you'll get samedrive->srequeststructure submitted twice toblk_insert_request(hm, Jens, will this trigger BUG, or will this just damage request list?).
Just silently damage request list. We _could_ easily add code to detect this, but it's not been a problem in the past so not worth looking for.
AFAICS, Petr is completely right wrt this race.
Signature · 1 line
Jens Axboe
Uz.ytkownik Jens Axboe napisa?:
Quoted 17 lines · Petr Vandrovec
Quoted 9 lines
Quoted 8 lines
After all
ide_raw_taskfileonly gets used forREQ_SPECIALrequest types. This does *not* contain normal data request from block IO. As of master slave issues - well we have the data pre allocated per device not per channel! Ifq->request_fnwould properly return the error count instead of void, we could even get rid ot the checking forrq->errorsafter finishment... But well that's entierly different story.Quoted 5 lines
For example
do_cmd_ioctl()invokeside_raw_taskfile, without any locking. Two programs, both issuingHDIO_DRIVE_CMDat same time, will compete over onedrive->srequeststruct: you'll get samedrive->srequeststructure submitted twice toblk_insert_request(hm, Jens, will this trigger BUG, or will this just damage request list?).
Quoted 4 lines
Just silently damage request list. We _could_ easily add code to detect this, but it's not been a problem in the past so not worth looking for.
AFAICS, Petr is completely right wrt this race.
For the ioctl case yes. But:
1. We already look for blk_queue_empty there.
2. We have just to deal properly with the queue plugging there to close it up.
3. I will just add spin locking on ide_lock to maintain that no two ioctl can overlapp at all.
OK?
Quoted 21 lines · Marcin Dalecki
Uz.ytkownik Jens Axboe napisa?:
Quoted 20 lines · Petr Vandrovec
Quoted 9 lines
Quoted 8 lines
After all
ide_raw_taskfileonly gets used forREQ_SPECIALrequest types. This does *not* contain normal data request from block IO. As of master slave issues - well we have the data pre allocated per device not per channel! Ifq->request_fnwould properly return the error count instead of void, we could even get rid ot the checking forrq->errorsafter finishment... But well that's entierly different story.Quoted 5 lines
For example
do_cmd_ioctl()invokeside_raw_taskfile, without any locking. Two programs, both issuingHDIO_DRIVE_CMDat same time, will compete over onedrive->srequeststruct: you'll get samedrive->srequeststructure submitted twice toblk_insert_request(hm, Jens, will this trigger BUG, or will this just damage request list?).Just silently damage request list. We _could_ easily add code to detect this, but it's not been a problem in the past so not worth looking for.
Quoted 7 lines
Quoted 1 line
AFAICS, Petr is completely right wrt this race.
For the ioctl case yes. But:
1. We already look for
blk_queue_emptythere.
2. We have just to deal properly with the queue plugging there to close it up.
I don't know what you mean here. Clearly this is an ide problem. If you have a statically allocated request, you _must_ serialize that yourself.
Quoted 2 lines
3. I will just add spin locking on
ide_lockto maintain that no two ioctl can overlapp at all.
Agrh god no. So you'll spin waiting for the ioctl to complete?
Quoted 1 line
From
ide_raw_taskfile(), the right way to do it is:
struct request *rq = blk_get_request(...);
This gets _everything_ right.
BTW, _glad to see you got rid of the horrible insert-and-execute stuff in ide_raw_taskfile(). That was a layering violation.
Quoted 1 line
OK?
Not likely :-)
Signature · 1 line
Jens Axboe
Uz.ytkownik Jens Axboe napisa?:
Quoted 8 lines
Agrh god no. So you'll spin waiting for the ioctl to complete?
Quoted 1 line
From
ide_raw_taskfile(), the right way to do it is:struct request *rq = blk_get_request(...);This gets _everything_ right.
Quoted 8 lines
BTW,
_gladto see you got rid of the horrible insert-and-execute stuff inide_raw_taskfile(). That was a layering violation.Quoted 1 line
OK?
Not likely :-)
Argh. Yes. Thank's for the back-head slap.
I was looking too much at the SCSI code again and got it wrong. But some time ago I was already thinking about blk_get_request(). How could I maintain that the blk_get_request() really returns? blk_get_request() does only drain up to maximum queue depth as far as I can read the code and then bad things wil happen :-). Or should I just not worry?
Quoted 19 lines · Marcin Dalecki
Uz.ytkownik Jens Axboe napisa?:
Quoted 8 lines
Agrh god no. So you'll spin waiting for the ioctl to complete?
Quoted 1 line
From
ide_raw_taskfile(), the right way to do it is:struct request *rq = blk_get_request(...);This gets _everything_ right.
Quoted 8 lines
BTW,
_gladto see you got rid of the horrible insert-and-execute stuff inide_raw_taskfile(). That was a layering violation.Quoted 1 line
OK?
Not likely :-)
Quoted 7 lines
Argh. Yes. Thank's for the back-head slap.
I was looking too much at the SCSI code again and got it wrong. But some time ago I was already thinking aboutblk_get_request(). How could I maintain that theblk_get_request()really returns?blk_get_request()does only drain up to maximum queue depth as far as I can read the code and then bad things wil happen :-). Or should I just not worry?
You can make it do what you want. From ioctl etc context (or basically anyone calling ide_raw_taskfile() since that will block too), you can use a blocking call to blk_get_request(). So
rq = blk_get_request(q, WRITE, __GFP_WAIT);
will _never_ return NULL. You are basically throttling on the freelist of the queue, just like any other submitter of I/O. And that, is a Good Thing :-)
Signature · 1 line
Jens Axboe