Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a74c0fb authored by Michael Butler's avatar Michael Butler
Browse files

Invalidate NN interface objects on cache mismatch

Currently, if an IDevice object is a DEAD_OBJECT, the runtime attempts
to re-retrieve the handle to the rebooted IDevice service. If an update
occurs after the IDevice was originally created, the rebooted IDevice
object may have different metadata and behavior. This is problematic
because the original metadata is cached in the runtime. Further, an
application might have made decisions based on that metadata and
behavior. (Note that a driver service that is functionally the same but
has a different underlying implementation such as having more optimized
code will have different `getVersionString` metadata.) Instead, this CL
invalidates the IDevice object on cache mismatch, and always returns an
error if it is used.

Bug: 173081926
Test: mma
Change-Id: I805987361c627c32d45e1b7c7aed230376fc66ad
parent f51af3b7
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BUFFER_H
#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BUFFER_H

#include <nnapi/IBuffer.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>

#include <memory>
#include <utility>
#include <vector>

namespace android::hardware::neuralnetworks::utils {

class InvalidBuffer final : public nn::IBuffer {
  public:
    nn::Request::MemoryDomainToken getToken() const override;

    nn::GeneralResult<void> copyTo(const nn::Memory& dst) const override;

    nn::GeneralResult<void> copyFrom(const nn::Memory& src,
                                     const nn::Dimensions& dimensions) const override;
};

}  // namespace android::hardware::neuralnetworks::utils

#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BUFFER_H
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_DEVICE_H
#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_DEVICE_H

#include <nnapi/IBuffer.h>
#include <nnapi/IDevice.h>
#include <nnapi/IPreparedModel.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>

#include <memory>
#include <string>
#include <vector>

namespace android::hardware::neuralnetworks::utils {

class InvalidDevice final : public nn::IDevice {
  public:
    InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel,
                  nn::DeviceType type, std::vector<nn::Extension> extensions,
                  nn::Capabilities capabilities,
                  std::pair<uint32_t, uint32_t> numberOfCacheFilesNeeded);

    const std::string& getName() const override;
    const std::string& getVersionString() const override;
    nn::Version getFeatureLevel() const override;
    nn::DeviceType getType() const override;
    const std::vector<nn::Extension>& getSupportedExtensions() const override;
    const nn::Capabilities& getCapabilities() const override;
    std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;

    nn::GeneralResult<void> wait() const override;

    nn::GeneralResult<std::vector<bool>> getSupportedOperations(
            const nn::Model& model) const override;

    nn::GeneralResult<nn::SharedPreparedModel> prepareModel(
            const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority,
            nn::OptionalTimePoint deadline, const std::vector<nn::SharedHandle>& modelCache,
            const std::vector<nn::SharedHandle>& dataCache,
            const nn::CacheToken& token) const override;

    nn::GeneralResult<nn::SharedPreparedModel> prepareModelFromCache(
            nn::OptionalTimePoint deadline, const std::vector<nn::SharedHandle>& modelCache,
            const std::vector<nn::SharedHandle>& dataCache,
            const nn::CacheToken& token) const override;

    nn::GeneralResult<nn::SharedBuffer> allocate(
            const nn::BufferDesc& desc, const std::vector<nn::SharedPreparedModel>& preparedModels,
            const std::vector<nn::BufferRole>& inputRoles,
            const std::vector<nn::BufferRole>& outputRoles) const override;

  private:
    const std::string kName;
    const std::string kVersionString;
    const nn::Version kFeatureLevel;
    const nn::DeviceType kType;
    const std::vector<nn::Extension> kExtensions;
    const nn::Capabilities kCapabilities;
    const std::pair<uint32_t, uint32_t> kNumberOfCacheFilesNeeded;
};

}  // namespace android::hardware::neuralnetworks::utils

#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_DEVICE_H
+48 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_PREPARED_MODEL_H
#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_PREPARED_MODEL_H

#include <nnapi/IPreparedModel.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>

#include <memory>
#include <utility>
#include <vector>

namespace android::hardware::neuralnetworks::utils {

class InvalidPreparedModel final : public nn::IPreparedModel {
  public:
    nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> execute(
            const nn::Request& request, nn::MeasureTiming measure,
            const nn::OptionalTimePoint& deadline,
            const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override;

    nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> executeFenced(
            const nn::Request& request, const std::vector<nn::SyncFence>& waitFor,
            nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline,
            const nn::OptionalTimeoutDuration& loopTimeoutDuration,
            const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override;

    std::any getUnderlyingResource() const override;
};

}  // namespace android::hardware::neuralnetworks::utils

#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_PREPARED_MODEL_H
+5 −2
Original line number Diff line number Diff line
@@ -45,8 +45,9 @@ class ResilientDevice final : public nn::IDevice,
                             std::string versionString, std::vector<nn::Extension> extensions,
                             nn::Capabilities capabilities, nn::SharedDevice device);

    nn::SharedDevice getDevice() const;
    nn::SharedDevice recover(const nn::IDevice* failingDevice, bool blocking) const;
    nn::SharedDevice getDevice() const EXCLUDES(mMutex);
    nn::SharedDevice recover(const nn::IDevice* failingDevice, bool blocking) const
            EXCLUDES(mMutex);

    const std::string& getName() const override;
    const std::string& getVersionString() const override;
@@ -78,6 +79,7 @@ class ResilientDevice final : public nn::IDevice,
            const std::vector<nn::BufferRole>& outputRoles) const override;

  private:
    bool isValidInternal() const EXCLUDES(mMutex);
    nn::GeneralResult<nn::SharedPreparedModel> prepareModelInternal(
            bool blocking, const nn::Model& model, nn::ExecutionPreference preference,
            nn::Priority priority, nn::OptionalTimePoint deadline,
@@ -100,6 +102,7 @@ class ResilientDevice final : public nn::IDevice,
    const nn::Capabilities kCapabilities;
    mutable std::mutex mMutex;
    mutable nn::SharedDevice mDevice GUARDED_BY(mMutex);
    mutable bool mIsValid GUARDED_BY(mMutex) = true;
};

}  // namespace android::hardware::neuralnetworks::utils
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "InvalidBuffer.h"

#include <nnapi/IBuffer.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>

#include <memory>
#include <utility>
#include <vector>

namespace android::hardware::neuralnetworks::utils {

nn::Request::MemoryDomainToken InvalidBuffer::getToken() const {
    return nn::Request::MemoryDomainToken{};
}

nn::GeneralResult<void> InvalidBuffer::copyTo(const nn::Memory& /*dst*/) const {
    return NN_ERROR() << "InvalidBuffer";
}

nn::GeneralResult<void> InvalidBuffer::copyFrom(const nn::Memory& /*src*/,
                                                const nn::Dimensions& /*dimensions*/) const {
    return NN_ERROR() << "InvalidBuffer";
}

}  // namespace android::hardware::neuralnetworks::utils
Loading