From nobody Fri Oct 2 13:03:29 2026 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA3C048987F for ; Fri, 31 Jul 2026 06:49:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785480601; cv=none; b=I+G9gxdssjRPZAdp/EUM4jHBO5RBuaO7/elJAYNYz015V4gGkKA2pwGCL2drzrIc3H3hKE0b7VWH/dOpUUwPiKc22xiE+j+n+Vx+tQYfiogUVUpzpO51ANCl8W/H3tCOHwTkr3kpg4j9YiuK6V6LKo2LIky51BByXGLty8sK0B8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785480601; c=relaxed/simple; bh=llWdlr+xs7S6gqsIBcINC3VyGdGrXqFW1L+lsyJPbjw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dURzM9jtokpyxz7PXVJgo2FGQ5O+6qIVDE6AFEL/2Nlrwb5mVy0b2Zc7MbsrReIjLv3oD162Qc65vtay5Sy4mKYCL0Ud2J8aYNPUiIVbO/CJk3hzBCP0nd0pKxoi/XMU7fiGZQU4TOBHc0oPiWXPcbdR1Xlzo53eei0mCdCRISo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=rjcs5Z7q; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rjcs5Z7q" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-47df6a5655aso71328f8f.1 for ; Thu, 30 Jul 2026 23:49:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785480598; x=1786085398; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=kXo8J24KrU8Vbaf2n2kgu1xGVPuRWaU3gl3iPntegac=; b=rjcs5Z7qyCUFOBi62rp6Qn76TYnQGP/+XSwpXy89zYyhK0T8NYLcPurwlrpLg300OT XD2DJbkWcQRXl+gm6CAP2UjFcvIqF+1w1Y8iI0DYvtbzav8rxJGHpK20zc/LeaqR4JvQ G6JzfB8YVefEMyj1eyFy6HIkAhYiQE91c1VtA2fPDiaD39jJHv+IA3A3pWYrjNeZ/dRW 0ExiWQGfrPZfcrgW8UdumlPvx4eryAXtkjrvCx4ga6GfPtZc86BaNvrPGYF4QBzlJ4XY hSF5p5LFq3Tqt51tKBm6WtASv7XmL3I03xnZkURT03LwgBJRpFhV/LCRV2ETzhL6bGqW oSiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785480598; x=1786085398; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=kXo8J24KrU8Vbaf2n2kgu1xGVPuRWaU3gl3iPntegac=; b=SLJHUVyyWd9K7qpyvuPHAJsTu6I7yXXT5jkBK7Iz1+ef6z86f8smBTq8ITGjGmAfeC me8Nclu0v1n6IspmwSyV5Ej+HnXfIX0r8Lr9FPlO6gxlxUHP2nWJ0/Z1C8C1I4DADKxT LnB4wdqBdmol6fcmaLK/Kppio9zMyS3B6zg5KMJOWmb9xZflFLEd8U4D2y2O+79RU9yl bP/zLgfNgvZrgJFtCQIUbXdkTH/NCVvWrqhc82/94Kj5qvBDyorrrevWKVZbfB5iHI2u BoKLBedjUGUeRKgJaRlDSdBASKIf7S/l8fxt6CnXSDUIePd3vRRerBxbbGQcZBPZGSzy 1tCg== X-Forwarded-Encrypted: i=1; AHgh+RrXd1+6aDWk31rLOAZxZ0X0/3OkiWh8BOaqabr+29fRroYCwQkB6NhZ2ZXYed/cMBdQ+0trvLq/t45QGOs=@vger.kernel.org X-Gm-Message-State: AOJu0YzJR9nMU9n83AV3Ah0/brGex3O4Kd3FymRFh5yleHVnEHC2heIt OkhmYMpIVe+LxlFy8spGvjLdR223mxG1K7lw2YeRYD3bp86D6/7K36/s X-Gm-Gg: AR+sD10y+zQMYmeVaOw6RoTOVf15JMG09qFn/l6qeFeHYRnSKoks9Fth0+2wSDQeiN4 qy4530XxdLTxEnRs0b0vHQ0+ywQhcjldiDSRH8itCwBMjrEDvUUNQ4gx00F3zYRSz14ie6pff6B FYzYJ02YhSxgZt4j8hlmtbOol9LYPKMsEZCl8wuuyWXq+ESdMRw6gqMm/U3i8GkDjS4UyUoAYR5 mMegQz8SeFUZ3mZjlrXaBxEsL/ifz+bRO5RuI78+AJUUQQVLdx1sT+ipA0g85oE+NiAo68QDxUB a3EeyQwwEW3WYFnuaFR7H4H1oAdUdigltXu1blKLZltq2An+lKnDQN0g6YyrMxaC1+psf14SeJb C/ZW7r5xxP5S+84b+Ays099j8Z2kLgIVXdr3IBzhqv6sWGohFXySV2NgHrfUHu7rryIIBBE8QaT +3Lp6cNrnv2IvA66DyCu+cZUtcRoOphmQbRjS5iQmI2rcXwvhavRZJjks/yOS8sRSk/GewOrgA4 YW6dNKEBJ3IEr7OfrGujFCYutu9moi9Tt02Sqo2kE43dYows6PpvW/THdgtIyc+noWbvQ== X-Received: by 2002:a05:6000:2401:b0:47f:96bc:e370 with SMTP id ffacd0b85a97d-47fd2b653fcmr2421972f8f.4.1785480597528; Thu, 30 Jul 2026 23:49:57 -0700 (PDT) Received: from OrangePi5-Plus.BB-HOME (20014C4E1B8B8B0053881A2C61CA978D.dsl.pool.telekom.hu. [2001:4c4e:1b8b:8b00:5388:1a2c:61ca:978d]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47fd41e2abbsm1212753f8f.9.2026.07.30.23.49.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jul 2026 23:49:57 -0700 (PDT) From: Igor Paunovic To: Tomeu Vizoso Cc: Oded Gabbay , Heiko Stuebner , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, Guangshuo Li , Jiaxing Hu , Igor Paunovic Subject: [PATCH v2 1/2] accel/rocket: release the shared device's devres on teardown Date: Fri, 31 Jul 2026 08:49:32 +0200 Message-ID: <20260731064933.12548-2-royalnet026@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260731064933.12548-1-royalnet026@gmail.com> References: <20260731064933.12548-1-royalnet026@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" rocket_device_init() attaches its allocations to the shared "rknn" platform device via devres: devm_drm_dev_alloc(), devm_kcalloc() for the cores array and devm_mutex_init(). That device is registered at module init, never binds to a driver, and is only unregistered at module exit - so its devres list is not released for as long as the module is loaded. rocket_device_fini() only calls drm_dev_unregister(): it does not run the drm_dev_put() devres action or free any of the other entries. Every fini/re-init cycle therefore leaks the previous rocket_device (with its embedded drm_device and all drmm state, including the accel minor number), the cores array and the mutex devres node. The cycle is easy to trigger: unbind the last bound core and bind one again, or fail the first core's probe (-EPROBE_DEFER retries included). Observable symptom, RK3588 (Orange Pi 5 Plus): each unbind/rebind cycle of all three cores moves the accel node forward - /dev/accel/accel0 comes back as accel1, then accel2 - because every leaked drm_device keeps its minor pinned. Wrap the initialization in a devres group and release exactly that group wherever the device is torn down: on the rocket_device_init() error path, when the first core's rocket_core_init() fails, and when the last core is removed. Each fini now frees what the matching init allocated, and the accel minor is reusable again. Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU") Signed-off-by: Igor Paunovic --- v2: unchanged. v1: https://lore.kernel.org/dri-devel/20260730080355.177422-2-royalnet026@g= mail.com/ This applies on top of Guangshuo Li's pending fix, which it depends on: "accel/rocket: clear rdev on device init failure" https://lore.kernel.org/dri-devel/20260708062845.716487-1-lgs201920130244@g= mail.com/ Verified on RK3588 (Orange Pi 5 Plus): with the patch, repeated unbind/rebind cycles keep /dev/accel/accel0 stable (previously the minor incremented on every cycle); normal three-core probe, runtime PM and a MobileNetV1 inference run via the Teflon TFLite delegate are unaffected. drivers/accel/rocket/rocket_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocke= t_drv.c index 67e7f54..d29c5ee 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -24,6 +24,7 @@ */ static struct platform_device *drm_dev; static struct rocket_device *rdev; +static void *rdev_group; =20 static void rocket_iommu_domain_destroy(struct kref *kref) @@ -163,14 +164,19 @@ static int rocket_probe(struct platform_device *pdev) =20 if (rdev =3D=3D NULL) { /* First core probing, initialize DRM device. */ + rdev_group =3D devres_open_group(&drm_dev->dev, NULL, GFP_KERNEL); + if (!rdev_group) + return -ENOMEM; rdev =3D rocket_device_init(drm_dev, &rocket_drm_driver); if (IS_ERR(rdev)) { int err =3D PTR_ERR(rdev); =20 dev_err(&pdev->dev, "failed to initialize rocket device\n"); rdev =3D NULL; + devres_release_group(&drm_dev->dev, rdev_group); return err; } + devres_close_group(&drm_dev->dev, rdev_group); } =20 unsigned int core =3D rdev->num_cores; @@ -190,6 +196,7 @@ static int rocket_probe(struct platform_device *pdev) if (rdev->num_cores =3D=3D 0) { rocket_device_fini(rdev); rdev =3D NULL; + devres_release_group(&drm_dev->dev, rdev_group); } } =20 @@ -213,6 +220,7 @@ static void rocket_remove(struct platform_device *pdev) /* Last core removed, deinitialize DRM device. */ rocket_device_fini(rdev); rdev =3D NULL; + devres_release_group(&drm_dev->dev, rdev_group); } } From nobody Fri Oct 2 13:03:29 2026 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A467525D53B for ; Fri, 31 Jul 2026 06:50:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785480602; cv=none; b=PfcI4jsVe60IwvmhGMjlrRHgUALrlkp7Xms75VZc0Quw6YDqAgqfCct6a1yBTutyS2udi0cWh/pu0s9aGgY3NHcrixGQV55JeohDnDG1i+OX1AhD1woMhOjdRYv9nBp6sEqedjHdFfmJlgP3+fIwrVIe+gzxm6I7plT9A067kdw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785480602; c=relaxed/simple; bh=xAZBv2VEwehc6rV3HJXkyBBhI3mtehVvRF2UKsJ3ZrI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TXvTROKzO5COcxCPG59Swb7sCbJdWfIgyswmGsLOSkLJ9DrNMQUFYJ/zucbM/hP/ZYjv7JEHGO4pDcYuBMPsQroeY7adXMntv2NFxjHQi43rDienOBUT+Xzad4JlPFfOgqYC2JBQ9mYOqom2/WWm+aKXTjA8o5R9Gf85fiiBxNg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NH0FOPQR; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NH0FOPQR" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-46f88060e8dso46555f8f.2 for ; Thu, 30 Jul 2026 23:50:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785480599; x=1786085399; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=894kL84WjsJ4NuY8JNzhxDjW08BYyE5HOdttjtE66tc=; b=NH0FOPQRcPQENlhvYHanINn/H/uhMOK6k4ovGOuVhKlqjrbIxE+R4XR6IJCI4gXfcN onkPHLzH2ckY8hAUBce18lIrTcE6SJ4luuK5hoxtC252vQQ6OMmnT52skRtKnUcjPJ2E z2kCrv1VqQtrmvGjfuaBh37sValCRWiM9Aahs5M/g00nFhpbpKlJ7FwiNfgC/pIvWYhP ceZBcrZsjTmT/xqdfGH6z4FzdAWdA77pLUpHxFYf2GnkYKqle+OvuNAv6clqUF76sMUF 4NVj2lJcK3njZ9ywcSdp8DTJjCXfsUKybv3iuta0KKPv5qPAUMMh4tq0briykQZpum5Y Rw8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785480599; x=1786085399; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=894kL84WjsJ4NuY8JNzhxDjW08BYyE5HOdttjtE66tc=; b=M50LNKiIYaHBXBalO3J9Ab9GMJZJTPWqUliaZYINTcVX6QlVcS/x3MX8QVYxXD9Kge AJ0/SIxLLPuISsAXGVObH51yLt+m4fM4guCOi5JbR9GBKTYiskAj9MNmIWpqrXbKnlf8 LFhi5FiVWEdXRmtERZqpdKiV4VBwufmX2ZPAD0Tep2rpDWcXtTRlY4uGQZBJYJfMlWm+ iYtzDFXSy/Nn7Z3Gt/9fNWnNj7o/UFThrr0EG5nVAsF8GZrDsWvuCBZ2NVtje2/4Bsvz iIcUgVPQxvInKvfPSI5EJvnjs5w02RNRpE4PlQ0/ratc8WdMkgILnWHrJ9AlrSD64/vI D1zQ== X-Forwarded-Encrypted: i=1; AHgh+RoLpSd4jjOCAUTA4ojCuXsdj1hLMkL0Pz+5JKUokIq2b2vvbmHly1SWlYELWvzgSQvvMTv5LCQZwxcdeso=@vger.kernel.org X-Gm-Message-State: AOJu0Ywps2OpWy//fPHnGHi98I/QaJrZJ5EyEtbc2/Yvng1NctGQRY2i FQgfvK3T6+GB7MiHvvdRC2hBzItP4ClREvEQ3TVqzRvOM22uJt/eBqvh X-Gm-Gg: AR+sD122+rPHIYH8GASXPlUiczgy6d6dpu88ydgEvAMddv1whbL6//ljHZI3dWKKuVN 88oVJMb9givVpbhUylmvqD5OG1314e+V8dLQgpDoedxje2VvMUDYZJKjMo2exHibAusrSpSsANK sy5LoowQVhroZTNl8KAjkI0gIXimbRegeSzqiuR5ZHqUD3JMMM4Cm10La7GkjuP8F3uP/AhcaA1 d66hG8qbiVDwkKr1OCL2qnH8dE9d3lySVe0sHGSpAe9KX3tx4UJrHyqzmo63j3RjN4Dn8qN0A5t 9IVpPpHh4rx7Ihv9ohPxYHNFJgAtr75IEIGhirETeEUsH5x38ITzyyVozt2FXMVB3MT121X++Nd /bvsjjq53n3DALgyS0KoIP9QJr4BVY7i0TS4MLj+AwZngxYII786E2vLCDgEvoIGw6pGssO+omt vfWr+ISXiSMiD6YtHplP1pcFkGtFp9s3+XYhcCfs44F+eV4AqGbupo4s1PJZ4CiUczCS9nk7Ln0 OW4mXCRBvyBJ86+AapWefYiXTJTR+S9dnsIpp9dem8cdF9p3ELb9oRWZkgDdpbTOJMgLs5RYhjb +eo8 X-Received: by 2002:a05:6000:41f8:b0:47f:946b:d3fc with SMTP id ffacd0b85a97d-47fd2b35e88mr2250807f8f.2.1785480598679; Thu, 30 Jul 2026 23:49:58 -0700 (PDT) Received: from OrangePi5-Plus.BB-HOME (20014C4E1B8B8B0053881A2C61CA978D.dsl.pool.telekom.hu. [2001:4c4e:1b8b:8b00:5388:1a2c:61ca:978d]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47fd41e2abbsm1212753f8f.9.2026.07.30.23.49.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jul 2026 23:49:58 -0700 (PDT) From: Igor Paunovic To: Tomeu Vizoso Cc: Oded Gabbay , Heiko Stuebner , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, Guangshuo Li , Jiaxing Hu , Igor Paunovic Subject: [PATCH v2 2/2] accel/rocket: keep core slots stable across unbind and rebind Date: Fri, 31 Jul 2026 08:49:33 +0200 Message-ID: <20260731064933.12548-3-royalnet026@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260731064933.12548-1-royalnet026@gmail.com> References: <20260731064933.12548-1-royalnet026@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The shared rocket_device tracks bound cores with a single counter and uses it for three different jobs at once: find_core_for_dev() searches [0, num_cores), rocket_probe() inserts the new core at index num_cores, and rocket_remove() only decrements the counter without clearing the slot. This bookkeeping falls apart as soon as cores are unbound in any order other than strict reverse bind order: - unbinding core 0 shrinks the search range, so the still-bound core at the highest index can no longer be found: its runtime PM callbacks start failing with -ENODEV and a later unbind of it is silently ignored, skipping rocket_core_fini() entirely; - a subsequent bind then reuses the index of that still-live core and overwrites its slot while its IRQ handler (dev_id points into cores[]) and its DRM scheduler are still active; - rocket_open() unconditionally uses cores[0].dev, which after an unbind of core 0 is a stale pointer to an unbound device. Give the array a fixed capacity (max_cores, the DT core count already used to size the allocation) and make .dev the slot-liveness marker: probe takes the first free slot and clears it again if core init fails, remove clears .dev after rocket_core_fini() and warns if the core cannot be found, lookups iterate the full capacity, and rocket_open() and rocket_job_open() use only live slots. num_cores keeps counting bound cores for the last-core teardown check. Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU") Signed-off-by: Igor Paunovic Reviewed-by: Jiaxing Hu --- v2: - also clear the slot's .dev when rocket_core_init() fails: with .dev as the liveness marker a failed init left a half-initialised core visible to every lookup, and rocket_job_open()'s live-slot walk could write one entry past its num_cores-sized allocation (Jiaxing Hu) - check .dev in sched_to_core() so skipping never-initialised slots is explicit rather than implied by pointer inequality (Jiaxing Hu) - document the synchronous-probe assumption at the slot scan v1: https://lore.kernel.org/dri-devel/20260730080355.177422-3-royalnet026@g= mail.com/ Unbinding a core that still has jobs in flight has further pre-existing issues (scheduler and open-file lifetime) that are out of scope for this bookkeeping fix. Verified on RK3588 (Orange Pi 5 Plus): out-of-order unbind/rebind sequences (including the previously corrupting unbind of core 0 with cores 1 and 2 still bound, followed by rebind) keep all three cores findable and functional, with MobileNetV1 inference via the Teflon TFLite delegate bit-identical to the stock driver. The new failure path was exercised by forcing rocket_core_init() to fail for core 2 with cores 0 and 1 already bound: the slot is released, the device comes up with the two remaining cores and inference passes bit-exact. drivers/accel/rocket/rocket_device.c | 2 ++ drivers/accel/rocket/rocket_device.h | 3 +++ drivers/accel/rocket/rocket_drv.c | 37 ++++++++++++++++++++++++++++++++= ---- drivers/accel/rocket/rocket_job.c | 13 +++++++------ 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/ro= cket_device.c index 46e6ee1..8303f05 100644 --- a/drivers/accel/rocket/rocket_device.c +++ b/drivers/accel/rocket/rocket_device.c @@ -35,6 +35,8 @@ struct rocket_device *rocket_device_init(struct platform_= device *pdev, if (!rdev->cores) return ERR_PTR(-ENOMEM); =20 + rdev->max_cores =3D num_cores; + dma_set_max_seg_size(dev, UINT_MAX); =20 err =3D dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); diff --git a/drivers/accel/rocket/rocket_device.h b/drivers/accel/rocket/ro= cket_device.h index ce662ab..7fb6a9d 100644 --- a/drivers/accel/rocket/rocket_device.h +++ b/drivers/accel/rocket/rocket_device.h @@ -18,6 +18,9 @@ struct rocket_device { struct mutex sched_lock; =20 struct rocket_core *cores; + /* Slot capacity (DT core count); slots with a NULL .dev are free. */ + unsigned int max_cores; + /* Number of currently bound cores. */ unsigned int num_cores; }; =20 diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocke= t_drv.c index d29c5ee..7d71a01 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -69,11 +69,21 @@ rocket_iommu_domain_put(struct rocket_iommu_domain *dom= ain) kref_put(&domain->kref, rocket_iommu_domain_destroy); } =20 +static struct rocket_core *rocket_first_live_core(struct rocket_device *rd= ev) +{ + for (unsigned int core =3D 0; core < rdev->max_cores; core++) + if (rdev->cores[core].dev) + return &rdev->cores[core]; + + return NULL; +} + static int rocket_open(struct drm_device *dev, struct drm_file *file) { struct rocket_device *rdev =3D to_rocket_device(dev); struct rocket_file_priv *rocket_priv; + struct rocket_core *core; u64 start, end; int ret; =20 @@ -86,8 +96,14 @@ rocket_open(struct drm_device *dev, struct drm_file *fil= e) goto err_put_mod; } =20 + core =3D rocket_first_live_core(rdev); + if (!core) { + ret =3D -ENODEV; + goto err_free; + } + rocket_priv->rdev =3D rdev; - rocket_priv->domain =3D rocket_iommu_domain_create(rdev->cores[0].dev); + rocket_priv->domain =3D rocket_iommu_domain_create(core->dev); if (IS_ERR(rocket_priv->domain)) { ret =3D PTR_ERR(rocket_priv->domain); goto err_free; @@ -179,10 +195,21 @@ static int rocket_probe(struct platform_device *pdev) devres_close_group(&drm_dev->dev, rdev_group); } =20 - unsigned int core =3D rdev->num_cores; + unsigned int core; =20 dev_set_drvdata(&pdev->dev, rdev); =20 + /* + * Take the first free slot: cores can unbind and rebind in any + * order. The scan-then-claim relies on platform probes running + * sequentially; revisit if the driver ever enables async probe. + */ + for (core =3D 0; core < rdev->max_cores; core++) + if (!rdev->cores[core].dev) + break; + if (WARN_ON(core =3D=3D rdev->max_cores)) + return -ENXIO; + rdev->cores[core].rdev =3D rdev; rdev->cores[core].dev =3D &pdev->dev; rdev->cores[core].index =3D core; @@ -191,6 +218,7 @@ static int rocket_probe(struct platform_device *pdev) =20 ret =3D rocket_core_init(&rdev->cores[core]); if (ret) { + rdev->cores[core].dev =3D NULL; rdev->num_cores--; =20 if (rdev->num_cores =3D=3D 0) { @@ -210,10 +238,11 @@ static void rocket_remove(struct platform_device *pde= v) struct device *dev =3D &pdev->dev; int core =3D find_core_for_dev(dev); =20 - if (core < 0) + if (WARN_ON(core < 0)) return; =20 rocket_core_fini(&rdev->cores[core]); + rdev->cores[core].dev =3D NULL; rdev->num_cores--; =20 if (rdev->num_cores =3D=3D 0) { @@ -234,7 +263,7 @@ static int find_core_for_dev(struct device *dev) { struct rocket_device *rdev =3D dev_get_drvdata(dev); =20 - for (unsigned int core =3D 0; core < rdev->num_cores; core++) { + for (unsigned int core =3D 0; core < rdev->max_cores; core++) { if (dev =3D=3D rdev->cores[core].dev) return core; } diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocke= t_job.c index ac51bff..0d8e69e 100644 --- a/drivers/accel/rocket/rocket_job.c +++ b/drivers/accel/rocket/rocket_job.c @@ -276,8 +276,8 @@ static struct rocket_core *sched_to_core(struct rocket_= device *rdev, { unsigned int core; =20 - for (core =3D 0; core < rdev->num_cores; core++) { - if (&rdev->cores[core].sched =3D=3D sched) + for (core =3D 0; core < rdev->max_cores; core++) { + if (rdev->cores[core].dev && &rdev->cores[core].sched =3D=3D sched) return &rdev->cores[core]; } =20 @@ -498,16 +498,17 @@ int rocket_job_open(struct rocket_file_priv *rocket_p= riv) struct rocket_device *rdev =3D rocket_priv->rdev; struct drm_gpu_scheduler **scheds =3D kmalloc_objs(*scheds, rdev->num_cores); - unsigned int core; + unsigned int core, n =3D 0; int ret; =20 - for (core =3D 0; core < rdev->num_cores; core++) - scheds[core] =3D &rdev->cores[core].sched; + for (core =3D 0; core < rdev->max_cores; core++) + if (rdev->cores[core].dev) + scheds[n++] =3D &rdev->cores[core].sched; =20 ret =3D drm_sched_entity_init(&rocket_priv->sched_entity, DRM_SCHED_PRIORITY_NORMAL, scheds, - rdev->num_cores, NULL); + n, NULL); if (WARN_ON(ret)) return ret;