Make VtsHalNeuralnetworks* tests more binder-friendly.
Certain mutation testing -- mutateOperandLifeTimeTest and
mutateOperandInputOutputTest -- can introduce potentially very large
CONSTANT_COPY operands, which can in turn create potentially very
large Models which must be passed across binder. To avoid overflowing
the binder buffer, we estimate the size of the mutated Model, and skip
the test if that size is too high. The old logic recognizes that our
tests only have a single active binder transaction at a time, and
assumes that there are no other clients using the same service at the
same time, and so we should have the binder buffer to ourselves; to be
conservative, we reject any Model whose estimated size exceeds half
the binder buffer size. Unfortunately, sometimes the binder buffer
still overflows, because it unexpectedly contains an allocation from
some other transaction: It appears that binder buffer memory
management is not serialized with respect to transactions from our
tests, and therefore depending on scheduler behavior, there may be a
sizeable allocation still in the buffer when we attempt to pass the
large Model. To fix this problem we become even more conservative,
and instead of limiting the Model to half the binder buffer size, we
limit it to half IBinder.MAX_IPC_SIZE (the recommended transaction
size limit). To confirm that this change does not exclude too many
tests, I checked how may times the size filter function
exceedsBinderSizeLimit is called, how many times it rejects a model
under the new logic (modelsExceedHalfMaxIPCSize), and how many times
it rejects a model under the old logic (modelsExceedHalfMaxIPCSize).
Test: VtsHalNeuralnetworksV1_0TargetTest --gtest_filter=TestGenerated/ValidationTest.Test/*-*dsp*
Test: # models = 3592, modelsExceedHalfMaxIPCSize = 212, modelsExceedHalfBufferSize = 18
Test: VtsHalNeuralnetworksV1_1TargetTest --gtest_filter=TestGenerated/ValidationTest.Test/*-*dsp*
Test: # models = 7228, modelsExceedHalfMaxIPCSize = 330, modelsExceedHalfBufferSize = 28
Test: VtsHalNeuralnetworksV1_2TargetTest --gtest_filter=TestGenerated/ValidationTest.Test/*-*dsp*
Test: # models = 52072, modelsExceedHalfMaxIPCSize = 506, modelsExceedHalfBufferSize = 28
Test: VtsHalNeuralnetworksV1_3TargetTest --gtest_filter=TestGenerated/ValidationTest.Test/*-*dsp*
Test: # models = 73342, modelsExceedHalfMaxIPCSize = 568, modelsExceedHalfBufferSize = 28
Test: VtsHalNeuralnetworksTargetTest
Bug: 227719657
Bug: 227719752
Bug: 231928847
Bug: 238777741
Bug: 242271308
Merged-In: I3f81d71ca3c0ad4c639096b1dc034a8909bc8971
Change-Id: I3f81d71ca3c0ad4c639096b1dc034a8909bc8971
(cherry picked from commit 79324920f7
)
This commit is contained in:
parent
be8ea4d3a8
commit
ce0048732a
5 changed files with 45 additions and 55 deletions
|
@ -232,26 +232,24 @@ size_t sizeForBinder(const Model& model) {
|
|||
// currently 1Mb, which is shared by all transactions in progress
|
||||
// for the process."
|
||||
//
|
||||
// Will our representation fit under this limit? There are two complications:
|
||||
// Will our representation fit under this limit? There are three complications:
|
||||
// - Our representation size is just approximate (see sizeForBinder()).
|
||||
// - This object may not be the only occupant of the Binder transaction buffer.
|
||||
// - This object may not be the only occupant of the Binder transaction buffer
|
||||
// (although our VTS test suite should not be putting multiple objects in the
|
||||
// buffer at once).
|
||||
// - IBinder.MAX_IPC_SIZE recommends limiting a transaction to 64 * 1024 bytes.
|
||||
// So we'll be very conservative: We want the representation size to be no
|
||||
// larger than half the transaction buffer size.
|
||||
// larger than half the recommended limit.
|
||||
//
|
||||
// If our representation grows large enough that it still fits within
|
||||
// the transaction buffer but combined with other transactions may
|
||||
// exceed the buffer size, then we may see intermittent HAL transport
|
||||
// errors.
|
||||
static bool exceedsBinderSizeLimit(size_t representationSize) {
|
||||
// Instead of using this fixed buffer size, we might instead be able to use
|
||||
// ProcessState::self()->getMmapSize(). However, this has a potential
|
||||
// problem: The binder/mmap size of the current process does not necessarily
|
||||
// indicate the binder/mmap size of the service (i.e., the other process).
|
||||
// The only way it would be a good indication is if both the current process
|
||||
// and the service use the default size.
|
||||
static const size_t kHalfBufferSize = 1024 * 1024 / 2;
|
||||
// There is no C++ API to retrieve the value of the Java variable IBinder.MAX_IPC_SIZE.
|
||||
static const size_t kHalfMaxIPCSize = 64 * 1024 / 2;
|
||||
|
||||
return representationSize > kHalfBufferSize;
|
||||
return representationSize > kHalfMaxIPCSize;
|
||||
}
|
||||
|
||||
///////////////////////// VALIDATE EXECUTION ORDER ////////////////////////////
|
||||
|
|
|
@ -252,26 +252,24 @@ size_t sizeForBinder(const Model& model) {
|
|||
// currently 1Mb, which is shared by all transactions in progress
|
||||
// for the process."
|
||||
//
|
||||
// Will our representation fit under this limit? There are two complications:
|
||||
// Will our representation fit under this limit? There are three complications:
|
||||
// - Our representation size is just approximate (see sizeForBinder()).
|
||||
// - This object may not be the only occupant of the Binder transaction buffer.
|
||||
// - This object may not be the only occupant of the Binder transaction buffer
|
||||
// (although our VTS test suite should not be putting multiple objects in the
|
||||
// buffer at once).
|
||||
// - IBinder.MAX_IPC_SIZE recommends limiting a transaction to 64 * 1024 bytes.
|
||||
// So we'll be very conservative: We want the representation size to be no
|
||||
// larger than half the transaction buffer size.
|
||||
// larger than half the recommended limit.
|
||||
//
|
||||
// If our representation grows large enough that it still fits within
|
||||
// the transaction buffer but combined with other transactions may
|
||||
// exceed the buffer size, then we may see intermittent HAL transport
|
||||
// errors.
|
||||
static bool exceedsBinderSizeLimit(size_t representationSize) {
|
||||
// Instead of using this fixed buffer size, we might instead be able to use
|
||||
// ProcessState::self()->getMmapSize(). However, this has a potential
|
||||
// problem: The binder/mmap size of the current process does not necessarily
|
||||
// indicate the binder/mmap size of the service (i.e., the other process).
|
||||
// The only way it would be a good indication is if both the current process
|
||||
// and the service use the default size.
|
||||
static const size_t kHalfBufferSize = 1024 * 1024 / 2;
|
||||
// There is no C++ API to retrieve the value of the Java variable IBinder.MAX_IPC_SIZE.
|
||||
static const size_t kHalfMaxIPCSize = 64 * 1024 / 2;
|
||||
|
||||
return representationSize > kHalfBufferSize;
|
||||
return representationSize > kHalfMaxIPCSize;
|
||||
}
|
||||
|
||||
///////////////////////// VALIDATE EXECUTION ORDER ////////////////////////////
|
||||
|
|
|
@ -291,26 +291,24 @@ size_t sizeForBinder(const Model& model) {
|
|||
// currently 1Mb, which is shared by all transactions in progress
|
||||
// for the process."
|
||||
//
|
||||
// Will our representation fit under this limit? There are two complications:
|
||||
// Will our representation fit under this limit? There are three complications:
|
||||
// - Our representation size is just approximate (see sizeForBinder()).
|
||||
// - This object may not be the only occupant of the Binder transaction buffer.
|
||||
// - This object may not be the only occupant of the Binder transaction buffer
|
||||
// (although our VTS test suite should not be putting multiple objects in the
|
||||
// buffer at once).
|
||||
// - IBinder.MAX_IPC_SIZE recommends limiting a transaction to 64 * 1024 bytes.
|
||||
// So we'll be very conservative: We want the representation size to be no
|
||||
// larger than half the transaction buffer size.
|
||||
// larger than half the recommended limit.
|
||||
//
|
||||
// If our representation grows large enough that it still fits within
|
||||
// the transaction buffer but combined with other transactions may
|
||||
// exceed the buffer size, then we may see intermittent HAL transport
|
||||
// errors.
|
||||
static bool exceedsBinderSizeLimit(size_t representationSize) {
|
||||
// Instead of using this fixed buffer size, we might instead be able to use
|
||||
// ProcessState::self()->getMmapSize(). However, this has a potential
|
||||
// problem: The binder/mmap size of the current process does not necessarily
|
||||
// indicate the binder/mmap size of the service (i.e., the other process).
|
||||
// The only way it would be a good indication is if both the current process
|
||||
// and the service use the default size.
|
||||
static const size_t kHalfBufferSize = 1024 * 1024 / 2;
|
||||
// There is no C++ API to retrieve the value of the Java variable IBinder.MAX_IPC_SIZE.
|
||||
static const size_t kHalfMaxIPCSize = 64 * 1024 / 2;
|
||||
|
||||
return representationSize > kHalfBufferSize;
|
||||
return representationSize > kHalfMaxIPCSize;
|
||||
}
|
||||
|
||||
///////////////////////// VALIDATE EXECUTION ORDER ////////////////////////////
|
||||
|
|
|
@ -308,26 +308,24 @@ size_t sizeForBinder(const Model& model) {
|
|||
// currently 1Mb, which is shared by all transactions in progress
|
||||
// for the process."
|
||||
//
|
||||
// Will our representation fit under this limit? There are two complications:
|
||||
// Will our representation fit under this limit? There are three complications:
|
||||
// - Our representation size is just approximate (see sizeForBinder()).
|
||||
// - This object may not be the only occupant of the Binder transaction buffer.
|
||||
// - This object may not be the only occupant of the Binder transaction buffer
|
||||
// (although our VTS test suite should not be putting multiple objects in the
|
||||
// buffer at once).
|
||||
// - IBinder.MAX_IPC_SIZE recommends limiting a transaction to 64 * 1024 bytes.
|
||||
// So we'll be very conservative: We want the representation size to be no
|
||||
// larger than half the transaction buffer size.
|
||||
// larger than half the recommended limit.
|
||||
//
|
||||
// If our representation grows large enough that it still fits within
|
||||
// the transaction buffer but combined with other transactions may
|
||||
// exceed the buffer size, then we may see intermittent HAL transport
|
||||
// errors.
|
||||
static bool exceedsBinderSizeLimit(size_t representationSize) {
|
||||
// Instead of using this fixed buffer size, we might instead be able to use
|
||||
// ProcessState::self()->getMmapSize(). However, this has a potential
|
||||
// problem: The binder/mmap size of the current process does not necessarily
|
||||
// indicate the binder/mmap size of the service (i.e., the other process).
|
||||
// The only way it would be a good indication is if both the current process
|
||||
// and the service use the default size.
|
||||
static const size_t kHalfBufferSize = 1024 * 1024 / 2;
|
||||
// There is no C++ API to retrieve the value of the Java variable IBinder.MAX_IPC_SIZE.
|
||||
static const size_t kHalfMaxIPCSize = 64 * 1024 / 2;
|
||||
|
||||
return representationSize > kHalfBufferSize;
|
||||
return representationSize > kHalfMaxIPCSize;
|
||||
}
|
||||
|
||||
///////////////////////// VALIDATE EXECUTION ORDER ////////////////////////////
|
||||
|
|
|
@ -344,26 +344,24 @@ size_t sizeForBinder(const Model& model) {
|
|||
// currently 1Mb, which is shared by all transactions in progress
|
||||
// for the process."
|
||||
//
|
||||
// Will our representation fit under this limit? There are two complications:
|
||||
// Will our representation fit under this limit? There are three complications:
|
||||
// - Our representation size is just approximate (see sizeForBinder()).
|
||||
// - This object may not be the only occupant of the Binder transaction buffer.
|
||||
// - This object may not be the only occupant of the Binder transaction buffer
|
||||
// (although our VTS test suite should not be putting multiple objects in the
|
||||
// buffer at once).
|
||||
// - IBinder.MAX_IPC_SIZE recommends limiting a transaction to 64 * 1024 bytes.
|
||||
// So we'll be very conservative: We want the representation size to be no
|
||||
// larger than half the transaction buffer size.
|
||||
// larger than half the recommended limit.
|
||||
//
|
||||
// If our representation grows large enough that it still fits within
|
||||
// the transaction buffer but combined with other transactions may
|
||||
// exceed the buffer size, then we may see intermittent HAL transport
|
||||
// errors.
|
||||
static bool exceedsBinderSizeLimit(size_t representationSize) {
|
||||
// Instead of using this fixed buffer size, we might instead be able to use
|
||||
// ProcessState::self()->getMmapSize(). However, this has a potential
|
||||
// problem: The binder/mmap size of the current process does not necessarily
|
||||
// indicate the binder/mmap size of the service (i.e., the other process).
|
||||
// The only way it would be a good indication is if both the current process
|
||||
// and the service use the default size.
|
||||
static const size_t kHalfBufferSize = 1024 * 1024 / 2;
|
||||
// There is no C++ API to retrieve the value of the Java variable IBinder.MAX_IPC_SIZE.
|
||||
static const size_t kHalfMaxIPCSize = 64 * 1024 / 2;
|
||||
|
||||
return representationSize > kHalfBufferSize;
|
||||
return representationSize > kHalfMaxIPCSize;
|
||||
}
|
||||
|
||||
///////////////////////// VALIDATE EXECUTION ORDER ////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue