diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index b8ecfa1168f3eed3ab4f549e6d3c144a988259b9..220058d8616d143d7afb386a395b818b60a855aa 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -22,6 +22,7 @@
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 #define NLMCLNT_GRACE_WAIT	(5*HZ)
 #define NLMCLNT_POLL_TIMEOUT	(30*HZ)
+#define NLMCLNT_MAX_RETRIES	3
 
 static int	nlmclnt_test(struct nlm_rqst *, struct file_lock *);
 static int	nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
@@ -802,6 +803,9 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
 	return;
 
 retry_cancel:
+	/* Don't ever retry more than 3 times */
+	if (req->a_retries++ >= NLMCLNT_MAX_RETRIES)
+		goto die;
 	nlm_rebind_host(req->a_host);
 	rpc_restart_call(task);
 	rpc_delay(task, 30 * HZ);
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index afe9a8f5c5aed71f0cf4531b4c74fccf313b559a..920766cea79cbc15634411e4c9633c27f6c8fd61 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -84,6 +84,7 @@ struct nlm_rqst {
 	struct nlm_args		a_args;		/* arguments */
 	struct nlm_res		a_res;		/* result */
 	struct nlm_wait *	a_block;
+	unsigned int		a_retries;	/* Retry count */
 	char			a_owner[NLMCLNT_OHSIZE];
 };