*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* @{
*/
-#include <linux/signal.h>
#include <libcfs/libcfs.h>
#include <lustre/lustre_idl.h>
#include <lustre_ver.h>
-#include <lustre_cfg.h>
+#include <uapi/linux/lustre_cfg.h>
/* target.c */
struct ptlrpc_request;
#define LP_POISON ((void *)LL_POISON)
#ifdef HAVE_SERVER_SUPPORT
-void target_client_add_cb(struct obd_device *obd, __u64 transno, void *cb_data,
- int error);
int rev_import_init(struct obd_export *exp);
int target_handle_connect(struct ptlrpc_request *req);
int target_handle_disconnect(struct ptlrpc_request *req);
for (;;) { \
set_current_state(TASK_INTERRUPTIBLE); \
\
+ /* To guarantee that the condition check will be done */ \
+ /* after setting the thread state as TASK_INTERRUPTIBLE. */ \
+ /* Otherwise, out-of-order execution may cause some race. */ \
+ /* Consider the following real execution order: */ \
+ \
+ /* 1. Thread1 checks condition on CPU1, gets false. */ \
+ /* 2. Thread2 sets condition on CPU2. */ \
+ /* 3. Thread2 calls wake_up() on CPU2 to wake the threads */ \
+ /* with state TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE. */ \
+ /* But the Thread1's state is TASK_RUNNING at that time. */ \
+ /* 4. Thread1 sets its state as TASK_INTERRUPTIBLE on CPU1, */ \
+ /* then schedule. */ \
+ \
+ /* If the '__timeout' variable is zero, the Thread1 will */ \
+ /* have no chance to check the condition again. */ \
+ \
+ /* Generally, the interval between out-of-ordered step1 and */ \
+ /* step4 is very tiny, as to above step2 and step3 cannot */ \
+ /* happen. On some degree, it can explain why we seldom hit */ \
+ /* related trouble. But such race really exists, especially */ \
+ /* consider that the step1 and step4 can be interruptible. */ \
+ /* So add barrier to avoid Thread1 out-of-order execution. */ \
+ smp_mb(); \
+ \
if (condition) \
break; \
\