<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">Understood, thanks.&nbsp; The fact that it's used for page locking elsewhere in Linux is plenty for me, was just curious.</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">Thanks,</p>
<p style="margin-top:0;margin-bottom:0">- Patrick</p>
<br>
<br>
<div style="color: rgb(0, 0, 0);">
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> NeilBrown &lt;neilb@suse.com&gt;<br>
<b>Sent:</b> Sunday, December 9, 2018 7:26 PM<br>
<b>To:</b> Patrick Farrell; James Simmons; Oleg Drokin; Andreas Dilger<br>
<b>Cc:</b> Lustre Development List<br>
<b>Subject:</b> Re: [lustre-devel] [PATCH 3/4] lustre: use bit-locking in echo_client.</font>
<div>&nbsp;</div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">On Mon, Dec 10 2018, Patrick Farrell wrote:<br>
<br>
&gt; Neil,<br>
&gt;<br>
&gt; So the semantics and behavior for a single bit bit lock and a mutex are the same?&nbsp; All the scheduler stuff, optimistic spin, etc?&nbsp; It may not matter here (probably not) but it makes me curious...<br>
<br>
No, not exactly the same - but close enough in this case.<br>
<br>
We don't get the optimistic spinning, and if there are multiple waiters<br>
they will all be woken when the lock is released, instead of just one.<br>
<br>
What we gain is a locking mechanism used in echo_client that is nearly<br>
identical to the locking mechansim (lock_page()) that is used for the<br>
normal Linux client.<br>
<br>
So yes, there are minor differences, I don't think they are important.<br>
I should have clarified that in the commit message.<br>
<br>
Thanks,<br>
NeilBrown<br>
<br>
<br>
&gt;<br>
&gt; - Patrick<br>
&gt;<br>
&gt; ________________________________<br>
&gt; From: lustre-devel &lt;lustre-devel-bounces@lists.lustre.org&gt; on behalf of NeilBrown &lt;neilb@suse.com&gt;<br>
&gt; Sent: Sunday, December 9, 2018 6:46:16 PM<br>
&gt; To: James Simmons; Oleg Drokin; Andreas Dilger<br>
&gt; Cc: Lustre Development List<br>
&gt; Subject: [lustre-devel] [PATCH 3/4] lustre: use bit-locking in echo_client.<br>
&gt;<br>
&gt; The ep_lock used by echo client causes lockdep to complain.<br>
&gt; Multiple locks of the same class are taken concurrently which<br>
&gt; appear to lockdep to be prone to deadlocking, and can fill up<br>
&gt; lockdep's fixed size stack for locks.<br>
&gt;<br>
&gt; Ass ep_lock is taken on multiple pages always in ascending page order,<br>
&gt; deadlocks don't happen, so this is a false-positive.<br>
&gt;<br>
&gt; The function of the ep_lock is the same as thats for page_lock(),<br>
&gt; which is implemented as a bit-lock using wait_on_bit().&nbsp; lockdep<br>
&gt; cannot see these locks, and doesn't really need to.<br>
&gt;<br>
&gt; So convert ep_lock to a simple bit-lock using wait_on_bit for<br>
&gt; waiting.&nbsp; This provides similar functionality, matches how page_lock()<br>
&gt; works, and avoids lockdep problems.<br>
&gt;<br>
&gt; Signed-off-by: NeilBrown &lt;neilb@suse.com&gt;<br>
&gt; ---<br>
&gt;&nbsp; .../staging/lustre/lustre/obdecho/echo_client.c&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; 29 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;-------<br>
&gt;&nbsp; 1 file changed, 19 insertions(&#43;), 10 deletions(-)<br>
&gt;<br>
&gt; diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c<br>
&gt; index 1ddb4a6dd8f3..887df7ce6b5c 100644<br>
&gt; --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c<br>
&gt; &#43;&#43;&#43; b/drivers/staging/lustre/lustre/obdecho/echo_client.c<br>
&gt; @@ -78,7 &#43;78,7 @@ struct echo_object_conf {<br>
&gt;<br>
&gt;&nbsp; struct echo_page {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct cl_page_slice&nbsp;&nbsp; ep_cl;<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct mutex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ep_lock;<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ep_lock;<br>
&gt;&nbsp; };<br>
&gt;<br>
&gt;&nbsp; struct echo_lock {<br>
&gt; @@ -217,10 &#43;217,13 @@ static int echo_page_own(const struct lu_env *env,<br>
&gt;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct echo_page *ep = cl2echo_page(slice);<br>
&gt;<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!nonblock)<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_lock(&amp;ep-&gt;ep_lock);<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (!mutex_trylock(&amp;ep-&gt;ep_lock))<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EAGAIN;<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nonblock) {<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (test_and_set_bit(0, &amp;ep-&gt;ep_lock))<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EAGAIN;<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (test_and_set_bit(0, &amp;ep-&gt;ep_lock))<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wait_on_bit(&amp;ep-&gt;ep_lock, 0, TASK_UNINTERRUPTIBLE);<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>
&gt;&nbsp; }<br>
&gt;<br>
&gt; @@ -230,8 &#43;233,8 @@ static void echo_page_disown(const struct lu_env *env,<br>
&gt;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct echo_page *ep = cl2echo_page(slice);<br>
&gt;<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LASSERT(mutex_is_locked(&amp;ep-&gt;ep_lock));<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_unlock(&amp;ep-&gt;ep_lock);<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LASSERT(test_bit(0, &amp;ep-&gt;ep_lock));<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clear_and_wake_up_bit(0, &amp;ep-&gt;ep_lock);<br>
&gt;&nbsp; }<br>
&gt;<br>
&gt;&nbsp; static void echo_page_discard(const struct lu_env *env,<br>
&gt; @@ -244,7 &#43;247,7 @@ static void echo_page_discard(const struct lu_env *env,<br>
&gt;&nbsp; static int echo_page_is_vmlocked(const struct lu_env *env,<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct cl_page_slice *slice)<br>
&gt;&nbsp; {<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mutex_is_locked(&amp;cl2echo_page(slice)-&gt;ep_lock))<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (test_bit(0, &amp;cl2echo_page(slice)-&gt;ep_lock))<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENODATA;<br>
&gt;&nbsp; }<br>
&gt; @@ -279,7 &#43;282,7 @@ static int echo_page_print(const struct lu_env *env,<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct echo_page *ep = cl2echo_page(slice);<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*printer)(env, cookie, LUSTRE_ECHO_CLIENT_NAME &quot;-page@%p %d vm@%p\n&quot;,<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ep, mutex_is_locked(&amp;ep-&gt;ep_lock),<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ep, test_bit(0, &amp;ep-&gt;ep_lock),<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; slice-&gt;cpl_page-&gt;cp_vmpage);<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>
&gt;&nbsp; }<br>
&gt; @@ -339,7 &#43;342,13 @@ static int echo_page_init(const struct lu_env *env, struct cl_object *obj,<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct echo_object *eco = cl2echo_obj(obj);<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get_page(page-&gt;cp_vmpage);<br>
&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mutex_init(&amp;ep-&gt;ep_lock);<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * ep_lock is similar to the lock_page() lock, and<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * cannot usefully be monitored by lockdep.<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * So just a bit in an &quot;unsigned long&quot; and use the<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * wait_on_bit() interface to wait for the bit to be clera.<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ep-&gt;ep_lock = 0;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cl_page_slice_add(page, &amp;ep-&gt;ep_cl, obj, index, &amp;echo_page_ops);<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; atomic_inc(&amp;eco-&gt;eo_npages);<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; lustre-devel mailing list<br>
&gt; lustre-devel@lists.lustre.org<br>
&gt; <a href="http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org" id="LPlnk668479" class="OWAAutoLink" previewremoved="true">
http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org</a>
<div id="LPBorder_GT_15444149028870.6582061015285363" style="margin-bottom: 20px; overflow: auto; width: 100%; text-indent: 0px;">
<table id="LPContainer_15444149028840.5490482717682608" role="presentation" cellspacing="0" style="width: 90%; background-color: rgb(255, 255, 255); position: relative; overflow: auto; padding-top: 20px; padding-bottom: 20px; margin-top: 20px; border-top: 1px dotted rgb(200, 200, 200); border-bottom: 1px dotted rgb(200, 200, 200);">
<tbody>
<tr valign="top" style="border-spacing: 0px;">
<td id="TextCell_15444149028850.006744044874555932" colspan="2" style="vertical-align: top; position: relative; padding: 0px; display: table-cell;">
<div id="LPRemovePreviewContainer_15444149028860.4480656383161399"></div>
<div id="LPTitle_15444149028860.9357260002399461" style="top: 0px; color: rgb(0, 114, 198); font-weight: 400; font-size: 21px; font-family: wf_segoe-ui_light, &quot;Segoe UI Light&quot;, &quot;Segoe WP Light&quot;, &quot;Segoe UI&quot;, &quot;Segoe WP&quot;, Tahoma, Arial, sans-serif; line-height: 21px;">
<a id="LPUrlAnchor_15444149028860.6191653030655315" href="http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org" target="_blank" style="text-decoration: none;">lustre-devel Info Page</a></div>
<div id="LPMetadata_15444149028860.4927041601254665" style="margin: 10px 0px 16px; color: rgb(102, 102, 102); font-weight: 400; font-family: wf_segoe-ui_normal, &quot;Segoe UI&quot;, &quot;Segoe WP&quot;, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 14px;">
lists.lustre.org</div>
<div id="LPDescription_15444149028870.1822831398061011" style="display: block; color: rgb(102, 102, 102); font-weight: 400; font-family: wf_segoe-ui_normal, &quot;Segoe UI&quot;, &quot;Segoe WP&quot;, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 20px; max-height: 100px; overflow: hidden;">
To see the collection of prior postings to the list, visit the lustre-devel Archives.. Using lustre-devel: To post a message to all the list members, send email to lustre-devel@lists.lustre.org. You can subscribe to the list, or change your existing subscription,
 in the sections below.</div>
</td>
</tr>
</tbody>
</table>
</div>
<br>
<br>
</div>
</span></font></div>
</div>
</div>
</body>
</html>