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

Commit 88a83501 authored by Girish's avatar Girish
Browse files

resourcemanager: importance based resource reclaim

Extend the reclaim policy by implementing codec importance
based resource reclaim.
User (of the codec) will assign codec importance to
distinguish important codecs from less important.
Upon resource conflict, the Resource Manager Service
reclaims a codec with the lowest importance (lower than that of
the requesting codec) from the same process (if there is one).

Bug: 289097671
Test: atest android.media.misc.cts.ResourceManagerTest
      atest android.media.misc.cts.ResourceManagerMultiTest
      /data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
      /data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
Change-Id: I383d88c852edae53d3eca24d7b563f133a63acaa
parent 6c16adb3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ cc_library {
    name: "libresourcemanagerservice",

    srcs: [
        "ClientImportanceReclaimPolicy.cpp",
        "DefaultResourceModel.cpp",
        "ProcessPriorityReclaimPolicy.cpp",
        "ResourceManagerMetrics.cpp",
+88 −0
Original line number Diff line number Diff line
/*
**
** Copyright 2023, 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.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "ClientImportanceReclaimPolicy"
#include <utils/Log.h>

#include "ResourceTracker.h"
#include "ResourceManagerService.h"
#include "ClientImportanceReclaimPolicy.h"

namespace android {

using aidl::android::media::IResourceManagerClient;

ClientImportanceReclaimPolicy::ClientImportanceReclaimPolicy(
        const std::shared_ptr<ResourceTracker>& resourceTracker)
    : mResourceTracker(resourceTracker) {
}

ClientImportanceReclaimPolicy::~ClientImportanceReclaimPolicy() {
}

// Find the biggest client from the same process with the lowest importance
// than that of the requesting client.
bool ClientImportanceReclaimPolicy::getClients(const ReclaimRequestInfo& reclaimRequestInfo,
                                              const std::vector<ClientInfo>& clients,
                                              std::vector<ClientInfo>& targetClients) {
    pid_t callingPid = reclaimRequestInfo.mCallingPid;
    int32_t callingImportance = reclaimRequestInfo.mCallingClientImportance;
    MediaResource::Type type = reclaimRequestInfo.mResources[0].type;
    MediaResource::SubType subType = reclaimRequestInfo.mResources[0].subType;
    ClientInfo targetClient;
    // Look to find the biggest client with lowest importance from the same process that
    // has the other resources and with the given primary type.
    bool found = false;
    MediaResource::SubType primarySubType = subType;
    for (size_t index = 1; !found && (index < reclaimRequestInfo.mResources.size()); index++) {
        MediaResource::Type type = reclaimRequestInfo.mResources[index].type;
        MediaResource::SubType subType = reclaimRequestInfo.mResources[index].subType;
        found = mResourceTracker->getLeastImportantBiggestClient(
            callingPid, callingImportance,
            type, subType, primarySubType,
            clients, targetClient);
    }
    // If no success, then select the biggest client of primary type with lowest importance
    // from the same process.
    if (!found) {
        found = mResourceTracker->getLeastImportantBiggestClient(
            callingPid, callingImportance,
            type, subType, MediaResource::SubType::kUnspecifiedSubType,
            clients, targetClient);
    }
    // If we haven't found a client yet, then select the biggest client of different type
    // with lowest importance from the same process.
    // This is applicable for codec type only.
    if (!found) {
        if (type != MediaResource::Type::kSecureCodec &&
            type != MediaResource::Type::kNonSecureCodec) {
            return false;
        }
        MediaResourceType otherType = (type == MediaResource::Type::kSecureCodec) ?
            MediaResource::Type::kNonSecureCodec : MediaResource::Type::kSecureCodec;
        if (!mResourceTracker->getLeastImportantBiggestClient(
            callingPid, callingImportance,
            otherType, subType, MediaResource::SubType::kUnspecifiedSubType,
            clients, targetClient)) {
            return false;
        }
    }
    targetClients.emplace_back(targetClient);
    return true;
}
} // namespace android
+64 −0
Original line number Diff line number Diff line
/*
**
** Copyright 2023, 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_MEDIA_CLIENTIMPORTANCERECLAIMPOLICY_H_
#define ANDROID_MEDIA_CLIENTIMPORTANCERECLAIMPOLICY_H_

#include <media/MediaResource.h>
#include "IReclaimPolicy.h"

namespace android {

class ResourceTracker;
struct ClientInfo;

/*
 * Implementation of Reclaim Policy based on the client's importance.
 *
 * Find the least important (other than that of requesting client) client from the
 * same process (that is requesting for the resource).
 * If there are multiple clients with least importance, then pick the biggest
 * client among them.
 *
 */
class ClientImportanceReclaimPolicy : public IReclaimPolicy {
public:
    explicit ClientImportanceReclaimPolicy(const std::shared_ptr<ResourceTracker>& resourceTracker);

    virtual ~ClientImportanceReclaimPolicy();

    /*
     * Based on the client importance, identify and return the least important client of
     * the requesting process from the list of given clients that satisfy the resource requested.
     *
     * @param[in]  reclaimRequestInfo Information about the resource request
     * @param[in]  client List of clients to select from.
     * @param[out] targetClients Upon success, this will have the list of identified client(s).
     *
     * @return true on success, false otherwise
     */
    bool getClients(const ReclaimRequestInfo& reclaimRequestInfo,
                    const std::vector<ClientInfo>& clients,
                    std::vector<ClientInfo>& targetClients) override;

private:
    std::shared_ptr<ResourceTracker> mResourceTracker;
};

} // namespace android

#endif  // ANDROID_MEDIA_CLIENTIMPORTANCERECLAIMPOLICY_H_
+4 −4
Original line number Diff line number Diff line
@@ -492,9 +492,10 @@ void ResourceManagerService::getClientForResource_l(
}

bool ResourceManagerService::getTargetClients(
        int32_t callingPid,
        const ClientInfoParcel& clientInfo,
        const std::vector<MediaResourceParcel>& resources,
        std::vector<ClientInfo>& targetClients) {
    int32_t callingPid = clientInfo.pid;
    std::scoped_lock lock{mLock};
    if (!mProcessInfo->isPidTrusted(callingPid)) {
        pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
@@ -598,10 +599,9 @@ bool ResourceManagerService::getTargetClients(

Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInfo,
        const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
    int32_t callingPid = clientInfo.pid;
    std::string clientName = clientInfo.name;
    String8 log = String8::format("reclaimResource(callingPid %d, uid %d resources %s)",
            callingPid, clientInfo.uid, getString(resources).c_str());
            clientInfo.pid, clientInfo.uid, getString(resources).c_str());
    mServiceLog->add(log);
    *_aidl_return = false;

@@ -611,7 +611,7 @@ Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInf
    }

    std::vector<ClientInfo> targetClients;
    if (!getTargetClients(callingPid, resources, targetClients)) {
    if (!getTargetClients(clientInfo, resources, targetClients)) {
        // Nothing to reclaim from.
        ALOGI("%s: There aren't any clients to reclaim from", __func__);
        return Status::ok();
+7 −1
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ private:
    // Gets the list of all the clients who own the list of specified resource type
    // and satisfy the resource model and the reclaim policy.
    virtual bool getTargetClients(
        int32_t callingPid,
        const ClientInfoParcel& clientInfo,
        const std::vector<MediaResourceParcel>& resources,
        std::vector<ClientInfo>& targetClients);

@@ -233,6 +233,12 @@ private:
    virtual const std::map<int, ResourceInfos>& getResourceMap() const {
        return mMap;
    }
    // enable/disable process priority based reclaim and client importance based reclaim
    virtual void setReclaimPolicy(bool processPriority, bool clientImportance) {
        // Implemented by the refactored/new RMService
        (void)processPriority;
        (void)clientImportance;
    }
    // END: TEST only functions

protected:
Loading