block_session: add client-defined request tag

The new request tag allows a block-session client to uniquely correlate
acknowledgements with outstanding requests. Until now, this was possible
for read and write operations by taking the value of the request's
packet-stream offset. However, SYNC and TRIM requests do not carry any
packet-stream payload and thereby lack meaningful offset values. By
introducing the notion of a 'tag', we can support multiple outstanding
requests of any type and don't need to overload the meaning of the
'offset' value.

Issue #3274
This commit is contained in:
Norman Feske 2019-04-09 13:58:49 +02:00 committed by Christian Helmuth
parent a39474a245
commit e058adc4fe
2 changed files with 16 additions and 5 deletions

View File

@ -210,7 +210,7 @@ class Block::Request_stream : Genode::Noncopyable
Request request { .operation = operation, Request request { .operation = operation,
.success = false, .success = false,
.offset = packet.offset(), .offset = packet.offset(),
.tag = { 0 } }; .tag = { packet.tag().value } };
Response const response = packet_valid Response const response = packet_valid
? fn(request) ? fn(request)
@ -294,7 +294,8 @@ class Block::Request_stream : Genode::Noncopyable
packet = Packet_descriptor(packet, packet = Packet_descriptor(packet,
opcode(request.operation.type), opcode(request.operation.type),
request.operation.block_number, request.operation.block_number,
request.operation.count); request.operation.count,
Session::Tag{request.tag.value});
packet.succeeded(request.success); packet.succeeded(request.success);

View File

@ -52,9 +52,15 @@ class Block::Packet_descriptor : public Genode::Packet_descriptor
*/ */
enum Alignment { PACKET_ALIGNMENT = 11 }; enum Alignment { PACKET_ALIGNMENT = 11 };
/**
* Client-defined value for correlating acknowledgements with requests
*/
struct Tag { unsigned long value; };
private: private:
Opcode _op; /* requested operation */ Opcode _op; /* requested operation */
Tag _tag; /* client-defined request identifier */
sector_t _block_number; /* requested block number */ sector_t _block_number; /* requested block number */
Genode::size_t _block_count; /* number of blocks of operation */ Genode::size_t _block_count; /* number of blocks of operation */
bool _success; /* indicates success of operation */ bool _success; /* indicates success of operation */
@ -67,17 +73,18 @@ class Block::Packet_descriptor : public Genode::Packet_descriptor
Packet_descriptor(Genode::off_t offset=0, Genode::size_t size = 0) Packet_descriptor(Genode::off_t offset=0, Genode::size_t size = 0)
: :
Genode::Packet_descriptor(offset, size), Genode::Packet_descriptor(offset, size),
_op(READ), _block_number(0), _block_count(0), _success(false) _op(READ), _tag(), _block_number(0), _block_count(0), _success(false)
{ } { }
/** /**
* Constructor * Constructor
*/ */
Packet_descriptor(Packet_descriptor p, Opcode op, Packet_descriptor(Packet_descriptor p, Opcode op,
sector_t block_number, Genode::size_t block_count = 1) sector_t block_number, Genode::size_t block_count = 1,
Tag tag = { ~0U })
: :
Genode::Packet_descriptor(p.offset(), p.size()), Genode::Packet_descriptor(p.offset(), p.size()),
_op(op), _block_number(block_number), _op(op), _tag(tag), _block_number(block_number),
_block_count(block_count), _success(false) _block_count(block_count), _success(false)
{ } { }
@ -85,6 +92,7 @@ class Block::Packet_descriptor : public Genode::Packet_descriptor
sector_t block_number() const { return _block_number; } sector_t block_number() const { return _block_number; }
Genode::size_t block_count() const { return _block_count; } Genode::size_t block_count() const { return _block_count; }
bool succeeded() const { return _success; } bool succeeded() const { return _success; }
Tag tag() const { return _tag; }
void succeeded(bool b) { _success = b; } void succeeded(bool b) { _success = b; }
}; };
@ -113,6 +121,8 @@ struct Block::Session : public Genode::Session
typedef Packet_stream_tx::Channel<Tx_policy> Tx; typedef Packet_stream_tx::Channel<Tx_policy> Tx;
typedef Packet_descriptor::Tag Tag;
struct Info struct Info
{ {
Genode::size_t block_size; /* size of one block in bytes */ Genode::size_t block_size; /* size of one block in bytes */