lkml.org 
[lkml]   [2020]   [Mar]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 09/10] iommu/ioasid: Support ioasid_set quota adjustment
    Date
    IOASID set is allocated with an initial quota, at runtime there may be
    needs to balance IOASID resources among different VMs/sets.

    This patch adds a new API to adjust per set quota.

    Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
    ---
    drivers/iommu/ioasid.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
    include/linux/ioasid.h | 6 ++++++
    2 files changed, 50 insertions(+)

    diff --git a/drivers/iommu/ioasid.c b/drivers/iommu/ioasid.c
    index 27dce2cb5af2..5ac28862a1db 100644
    --- a/drivers/iommu/ioasid.c
    +++ b/drivers/iommu/ioasid.c
    @@ -578,6 +578,50 @@ void ioasid_free_set(int sid, bool destroy_set)
    }
    EXPORT_SYMBOL_GPL(ioasid_free_set);

    +/**
    + * ioasid_adjust_set - Adjust the quota of an IOASID set
    + * @quota: Quota allowed in this set
    + * @sid: IOASID set ID to be assigned
    + *
    + * Return 0 on success. If the new quota is smaller than the number of
    + * IOASIDs already allocated, -EINVAL will be returned. No change will be
    + * made to the existing quota.
    + */
    +int ioasid_adjust_set(int sid, int quota)
    +{
    + struct ioasid_set_data *sdata;
    + int ret = 0;
    +
    + mutex_lock(&ioasid_allocator_lock);
    + sdata = xa_load(&ioasid_sets, sid);
    + if (!sdata || sdata->nr_ioasids > quota) {
    + pr_err("Failed to adjust IOASID set %d quota %d\n",
    + sid, quota);
    + ret = -EINVAL;
    + goto done_unlock;
    + }
    +
    + if (quota >= ioasid_capacity_avail) {
    + ret = -ENOSPC;
    + goto done_unlock;
    + }
    +
    + /* Return the delta back to system pool */
    + ioasid_capacity_avail += sdata->size - quota;
    +
    + /*
    + * May have a policy to prevent giving all available IOASIDs
    + * to one set. But we don't enforce here, it should be in the
    + * upper layers.
    + */
    + sdata->size = quota;
    +
    +done_unlock:
    + mutex_unlock(&ioasid_allocator_lock);
    +
    + return ret;
    +}
    +EXPORT_SYMBOL_GPL(ioasid_adjust_set);

    /**
    * ioasid_find - Find IOASID data
    diff --git a/include/linux/ioasid.h b/include/linux/ioasid.h
    index 32d032913828..6e7de6fb91bf 100644
    --- a/include/linux/ioasid.h
    +++ b/include/linux/ioasid.h
    @@ -73,6 +73,7 @@ int ioasid_alloc_set(struct ioasid_set *token, ioasid_t quota, int *sid);
    void ioasid_free_set(int sid, bool destroy_set);
    int ioasid_find_sid(ioasid_t ioasid);
    int ioasid_notify(ioasid_t id, enum ioasid_notify_val cmd);
    +int ioasid_adjust_set(int sid, int quota);

    #else /* !CONFIG_IOASID */
    static inline ioasid_t ioasid_alloc(int sid, ioasid_t min,
    @@ -136,5 +137,10 @@ static inline int ioasid_alloc_system_set(int quota)
    return -ENOTSUPP;
    }

    +static inline int ioasid_adjust_set(int sid, int quota)
    +{
    + return -ENOTSUPP;
    +}
    +
    #endif /* CONFIG_IOASID */
    #endif /* __LINUX_IOASID_H */
    --
    2.7.4
    \
     
     \ /
      Last update: 2020-03-25 18:51    [W:3.627 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site