nfp: don't wait for resources indefinitely
authorJakub Kicinski <jakub.kicinski@netronome.com>
Mon, 29 May 2017 00:53:01 +0000 (17:53 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 30 May 2017 15:27:06 +0000 (11:27 -0400)
There is currently no timeout to the resource and lock acquiring
loops.  We printed warnings and depended on user sending a signal
to the waiting process to stop the waiting.  This doesn't work
very well when wait happens out of a work queue.  The simplest
example of that is PCI probe.  When user loads the module and card
is in a broken state modprobe will wait forever and signals sent
to it will not actually reach the probing thread.

Make sure all wait loops have a time out.  Set the upper wait time
to 60 seconds to stay on the safe side.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c

index 8d46b9acb69ffd82b1dd353e649c0b6b749bd5e6..0a46c0984e6869b385a33ccce2f98047b603a8d3 100644 (file)
 /* Max size of area it should be safe to request */
 #define NFP_CPP_SAFE_AREA_SIZE         SZ_2M
 
+/* NFP_MUTEX_WAIT_* are timeouts in seconds when waiting for a mutex */
+#define NFP_MUTEX_WAIT_FIRST_WARN      15
+#define NFP_MUTEX_WAIT_NEXT_WARN       5
+#define NFP_MUTEX_WAIT_ERROR           60
+
 struct device;
 
 struct nfp_cpp_area;
index 8a99c189efa8c3165a12ead6a4d4e44e1eb29805..f7b95818112636941f110673c5a1c32d5cbe1618 100644 (file)
@@ -195,7 +195,8 @@ void nfp_cpp_mutex_free(struct nfp_cpp_mutex *mutex)
  */
 int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex)
 {
-       unsigned long warn_at = jiffies + 15 * HZ;
+       unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
+       unsigned long err_at = jiffies + NFP_MUTEX_WAIT_ERROR * HZ;
        unsigned int timeout_ms = 1;
        int err;
 
@@ -214,12 +215,16 @@ int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex)
                        return -ERESTARTSYS;
 
                if (time_is_before_eq_jiffies(warn_at)) {
-                       warn_at = jiffies + 60 * HZ;
+                       warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
                        nfp_warn(mutex->cpp,
                                 "Warning: waiting for NFP mutex [depth:%hd target:%d addr:%llx key:%08x]\n",
                                 mutex->depth,
                                 mutex->target, mutex->address, mutex->key);
                }
+               if (time_is_before_eq_jiffies(err_at)) {
+                       nfp_err(mutex->cpp, "Error: mutex wait timed out\n");
+                       return -EBUSY;
+               }
        }
 
        return err;
index 2d15a7c9d0de33d6b3773e3c7da7ed49c694095d..072612263dabe92e76481a14cacebfa0cf513b4a 100644 (file)
@@ -181,7 +181,8 @@ err_unlock_dev:
 struct nfp_resource *
 nfp_resource_acquire(struct nfp_cpp *cpp, const char *name)
 {
-       unsigned long warn_at = jiffies + 15 * HZ;
+       unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
+       unsigned long err_at = jiffies + NFP_MUTEX_WAIT_ERROR * HZ;
        struct nfp_cpp_mutex *dev_mutex;
        struct nfp_resource *res;
        int err;
@@ -214,10 +215,15 @@ nfp_resource_acquire(struct nfp_cpp *cpp, const char *name)
                }
 
                if (time_is_before_eq_jiffies(warn_at)) {
-                       warn_at = jiffies + 60 * HZ;
+                       warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
                        nfp_warn(cpp, "Warning: waiting for NFP resource %s\n",
                                 name);
                }
+               if (time_is_before_eq_jiffies(err_at)) {
+                       nfp_err(cpp, "Error: resource %s timed out\n", name);
+                       err = -EBUSY;
+                       goto err_free;
+               }
        }
 
        nfp_cpp_mutex_free(dev_mutex);