|
10 | 10 | #include <drm/drm_managed.h> |
11 | 11 | #include <drm/drm_print.h> |
12 | 12 | #include <drm/gpu_scheduler.h> |
| 13 | +#include <linux/cleanup.h> |
13 | 14 | #include <linux/errno.h> |
14 | 15 | #include <linux/firmware.h> |
15 | 16 | #include <linux/iommu.h> |
@@ -465,8 +466,11 @@ static int aie2_hw_resume(struct amdxdna_dev *xdna) |
465 | 466 | return ret; |
466 | 467 | } |
467 | 468 |
|
468 | | - list_for_each_entry(client, &xdna->client_list, node) |
469 | | - aie2_hwctx_resume(client); |
| 469 | + list_for_each_entry(client, &xdna->client_list, node) { |
| 470 | + ret = aie2_hwctx_resume(client); |
| 471 | + if (ret) |
| 472 | + break; |
| 473 | + } |
470 | 474 |
|
471 | 475 | return ret; |
472 | 476 | } |
@@ -779,65 +783,56 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, |
779 | 783 | return ret; |
780 | 784 | } |
781 | 785 |
|
| 786 | +static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) |
| 787 | +{ |
| 788 | + struct amdxdna_drm_query_hwctx __user *buf, *tmp __free(kfree) = NULL; |
| 789 | + struct amdxdna_drm_get_info *get_info_args = arg; |
| 790 | + |
| 791 | + if (get_info_args->buffer_size < sizeof(*tmp)) |
| 792 | + return -EINVAL; |
| 793 | + |
| 794 | + tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
| 795 | + if (!tmp) |
| 796 | + return -ENOMEM; |
| 797 | + |
| 798 | + tmp->pid = hwctx->client->pid; |
| 799 | + tmp->context_id = hwctx->id; |
| 800 | + tmp->start_col = hwctx->start_col; |
| 801 | + tmp->num_col = hwctx->num_col; |
| 802 | + tmp->command_submissions = hwctx->priv->seq; |
| 803 | + tmp->command_completions = hwctx->priv->completed; |
| 804 | + |
| 805 | + buf = u64_to_user_ptr(get_info_args->buffer); |
| 806 | + |
| 807 | + if (copy_to_user(buf, tmp, sizeof(*tmp))) |
| 808 | + return -EFAULT; |
| 809 | + |
| 810 | + get_info_args->buffer += sizeof(*tmp); |
| 811 | + get_info_args->buffer_size -= sizeof(*tmp); |
| 812 | + |
| 813 | + return 0; |
| 814 | +} |
| 815 | + |
782 | 816 | static int aie2_get_hwctx_status(struct amdxdna_client *client, |
783 | 817 | struct amdxdna_drm_get_info *args) |
784 | 818 | { |
785 | | - struct amdxdna_drm_query_hwctx __user *buf; |
786 | 819 | struct amdxdna_dev *xdna = client->xdna; |
787 | | - struct amdxdna_drm_query_hwctx *tmp; |
| 820 | + struct amdxdna_drm_get_info info_args; |
788 | 821 | struct amdxdna_client *tmp_client; |
789 | | - struct amdxdna_hwctx *hwctx; |
790 | | - unsigned long hwctx_id; |
791 | | - bool overflow = false; |
792 | | - u32 req_bytes = 0; |
793 | | - u32 hw_i = 0; |
794 | | - int ret = 0; |
795 | | - int idx; |
| 822 | + int ret; |
796 | 823 |
|
797 | 824 | drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); |
798 | 825 |
|
799 | | - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
800 | | - if (!tmp) |
801 | | - return -ENOMEM; |
| 826 | + info_args.buffer = args->buffer; |
| 827 | + info_args.buffer_size = args->buffer_size; |
802 | 828 |
|
803 | | - buf = u64_to_user_ptr(args->buffer); |
804 | 829 | list_for_each_entry(tmp_client, &xdna->client_list, node) { |
805 | | - idx = srcu_read_lock(&tmp_client->hwctx_srcu); |
806 | | - amdxdna_for_each_hwctx(tmp_client, hwctx_id, hwctx) { |
807 | | - req_bytes += sizeof(*tmp); |
808 | | - if (args->buffer_size < req_bytes) { |
809 | | - /* Continue iterating to get the required size */ |
810 | | - overflow = true; |
811 | | - continue; |
812 | | - } |
813 | | - |
814 | | - memset(tmp, 0, sizeof(*tmp)); |
815 | | - tmp->pid = tmp_client->pid; |
816 | | - tmp->context_id = hwctx->id; |
817 | | - tmp->start_col = hwctx->start_col; |
818 | | - tmp->num_col = hwctx->num_col; |
819 | | - tmp->command_submissions = hwctx->priv->seq; |
820 | | - tmp->command_completions = hwctx->priv->completed; |
821 | | - |
822 | | - if (copy_to_user(&buf[hw_i], tmp, sizeof(*tmp))) { |
823 | | - ret = -EFAULT; |
824 | | - srcu_read_unlock(&tmp_client->hwctx_srcu, idx); |
825 | | - goto out; |
826 | | - } |
827 | | - hw_i++; |
828 | | - } |
829 | | - srcu_read_unlock(&tmp_client->hwctx_srcu, idx); |
830 | | - } |
831 | | - |
832 | | - if (overflow) { |
833 | | - XDNA_ERR(xdna, "Invalid buffer size. Given: %u Need: %u.", |
834 | | - args->buffer_size, req_bytes); |
835 | | - ret = -EINVAL; |
| 830 | + ret = amdxdna_hwctx_walk(tmp_client, &info_args, aie2_hwctx_status_cb); |
| 831 | + if (ret) |
| 832 | + break; |
836 | 833 | } |
837 | 834 |
|
838 | | -out: |
839 | | - kfree(tmp); |
840 | | - args->buffer_size = req_bytes; |
| 835 | + args->buffer_size = (u32)(info_args.buffer - args->buffer); |
841 | 836 | return ret; |
842 | 837 | } |
843 | 838 |
|
|
0 commit comments