|
@@ -249,6 +249,51 @@ void nfp_resource_release(struct nfp_resource *res)
|
|
|
kfree(res);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * nfp_resource_wait() - Wait for resource to appear
|
|
|
+ * @cpp: NFP CPP handle
|
|
|
+ * @name: Name of the resource
|
|
|
+ * @secs: Number of seconds to wait
|
|
|
+ *
|
|
|
+ * Wait for resource to appear in the resource table, grab and release
|
|
|
+ * its lock. The wait is jiffies-based, don't expect fine granularity.
|
|
|
+ *
|
|
|
+ * Return: 0 on success, errno otherwise.
|
|
|
+ */
|
|
|
+int nfp_resource_wait(struct nfp_cpp *cpp, const char *name, unsigned int secs)
|
|
|
+{
|
|
|
+ unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
|
|
|
+ unsigned long err_at = jiffies + secs * HZ;
|
|
|
+ struct nfp_resource *res;
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ res = nfp_resource_acquire(cpp, name);
|
|
|
+ if (!IS_ERR(res)) {
|
|
|
+ nfp_resource_release(res);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (PTR_ERR(res) != -ENOENT) {
|
|
|
+ nfp_err(cpp, "error waiting for resource %s: %ld\n",
|
|
|
+ name, PTR_ERR(res));
|
|
|
+ return PTR_ERR(res);
|
|
|
+ }
|
|
|
+ if (time_is_before_eq_jiffies(err_at)) {
|
|
|
+ nfp_err(cpp, "timeout waiting for resource %s\n", name);
|
|
|
+ return -ETIMEDOUT;
|
|
|
+ }
|
|
|
+ if (time_is_before_eq_jiffies(warn_at)) {
|
|
|
+ warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
|
|
|
+ nfp_info(cpp, "waiting for NFP resource %s\n", name);
|
|
|
+ }
|
|
|
+ if (msleep_interruptible(10)) {
|
|
|
+ nfp_err(cpp, "wait for resource %s interrupted\n",
|
|
|
+ name);
|
|
|
+ return -ERESTARTSYS;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* nfp_resource_cpp_id() - Return the cpp_id of a resource handle
|
|
|
* @res: NFP Resource handle
|