<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:宋体;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@宋体";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        text-align:justify;
        text-justify:inter-ideograph;
        font-size:10.5pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin:0cm;
        margin-bottom:.0001pt;
        text-align:justify;
        text-justify:inter-ideograph;
        text-indent:21.0pt;
        font-size:10.5pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle18
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
span.EmailStyle19
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1931498631;
        mso-list-type:hybrid;
        mso-list-template-ids:-386250478 350628334 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l0:level1
        {mso-level-text:"%1\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:18.0pt;
        text-indent:-18.0pt;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-text:"%2\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:42.0pt;
        text-indent:-21.0pt;}
@list l0:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        margin-left:63.0pt;
        text-indent:-21.0pt;}
@list l0:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:84.0pt;
        text-indent:-21.0pt;}
@list l0:level5
        {mso-level-number-format:alpha-lower;
        mso-level-text:"%5\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:105.0pt;
        text-indent:-21.0pt;}
@list l0:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        margin-left:126.0pt;
        text-indent:-21.0pt;}
@list l0:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:147.0pt;
        text-indent:-21.0pt;}
@list l0:level8
        {mso-level-number-format:alpha-lower;
        mso-level-text:"%8\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:168.0pt;
        text-indent:-21.0pt;}
@list l0:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        margin-left:189.0pt;
        text-indent:-21.0pt;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="ZH-CN" link="#0563C1" vlink="#954F72" style="text-justify-trim:punctuation">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">Hi ALL,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">This problem is fixed, update info as follows:
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoListParagraph" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo1">
<![if !supportLists]><span lang="EN-US" style="color:#1F497D"><span style="mso-list:Ignore">1)<span style="font:7.0pt "Times New Roman"">      
</span></span></span><![endif]><span lang="EN-US" style="color:#1F497D">The following patch can fix the problem  happened when using the testing code of the previous mail.<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:18.0pt;text-indent:0cm"><span lang="EN-US"><a href="https://www.mail-archive.com/ovs-dev@openvswitch.org/msg41202.html">https://www.mail-archive.com/ovs-dev@openvswitch.org/msg41202.html</a><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoListParagraph" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo1">
<![if !supportLists]><span lang="EN-US" style="color:#1F497D"><span style="mso-list:Ignore">2)<span style="font:7.0pt "Times New Roman"">      
</span></span></span><![endif]><span lang="EN-US" style="color:#1F497D">What we need here is a  memory_order_acquire sematics when getting impl->size, to make sure, the<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:18.0pt;text-indent:0cm"><span lang="EN-US" style="color:#1F497D">current cpu to get impl->vector content correctly.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoListParagraph" style="margin-left:18.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo1">
<![if !supportLists]><span lang="EN-US" style="color:#1F497D"><span style="mso-list:Ignore">3)<span style="font:7.0pt "Times New Roman"">      
</span></span></span><![endif]><span lang="EN-US" style="color:#1F497D">The key point here is release/consume,  release/require must be used in paired. If ptr is inserted<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:18.0pt;text-indent:0cm"><span lang="EN-US" style="color:#1F497D">into pvec->temp and published later with ovsrcu_set, ovsrcu_get could get the correct pvector->impl->vector<o:p></o:p></span></p>
<p class="MsoListParagraph" style="margin-left:18.0pt;text-indent:0cm"><span lang="EN-US" style="color:#1F497D">content (both ptr and *ptr). But sometimes pvector_insert is worked with impl unchanged,<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent:15.75pt"><span lang="EN-US" style="color:#1F497D">and only release impl->size, so impl->size need to be get use acquire sematics to get correct impl->vector<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent:15.75pt"><span lang="EN-US" style="color:#1F497D">content. pvector->size and pvector->vector has no data-dependent relationship, so acquire must be used here, not consume.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>Hi All,<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>Recently we found a problem, as follow:<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>1</span><span style="font-family:宋体;color:#1F497D">.</span><span lang="EN-US" style="color:#1F497D">         Problem description:<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>PVECTOR_FOR_EACH use ovsrcu_get to get pvector’s current impl pointer, and the memory_order_consume<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>in ovsrcu_get will ensure *impl is read after this instruction, so we can get the the correct ptr value in<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>impl->vector[0], but it seems that we cannot make sure that the *ptr value is also correct.<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>2</span><span style="font-family:宋体;color:#1F497D">.</span><span lang="EN-US" style="color:#1F497D">         Verification through testing:<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>Copy the test code into file lib/dpif-netdev.c, and the modify fuction pmd_thread_main, insert the following line<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>in the for (;;) loop</span><span style="font-family:宋体;color:#1F497D">:</span><span style="color:#1F497D">
<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>do_atomic_test(pmd);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>  if the do_atomic_consumer is implement without mutex lock, we can easily get the following log in ovs-vswitchd.log:<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>      ----my_itrator:143, my_value:144  (we may get other values, and my_itrator = my_value - 1 stay true.<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>   The consumer thread can get dirty memory with memory_order_consume, if we change ovsrcu_get to get values<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>   with memory_order_acquire, we can still get the error message (my_itrator = my_value - 1).<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">> 
<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>   We can fix this problem if consumer thread access data with g_pvector_lock’ protection, but pvector is designed<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>to use without locks. Where did it go wrong? Can anyone here give some comments?<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>--------------------------------------------- A error case truly happened whining using pvector --------------------------<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>Suppose a scenario as follows:<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>1)   handler thread insert a dpcls_subtable, whose address is p,
<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>to datapath classifier’s (struct dpcls) pvector;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>2)   pmd thread call fast_path_processing to find the subtable and access address p;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>3)   the subtable above is destroyed by someone;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>4)   handler thread insert another subtable, whose address is also p,<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>and insert to dpcls’s pvector;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>5)   pmd thread call fast_path_processing -> dp_netdev_pmd_lookup_flow<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>-> dpcls_lookup to access the subtable from pvector.<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>We use PVECTOR_FOR_EACH to iterate the pvector in step 5, no locks is used, dirty memory access may<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>cause to ovs-vswitchd process coredump.<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>----------------------------------------------Testing codes are as follows ---------------------------------------------<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static struct pvector  g_atomic_test;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static unsigned char  g_my_data[65536];<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static unsigned char  g_value = 0;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static int    g_index = 0;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static struct ovs_mutex g_pvector_lock = OVS_MUTEX_INITIALIZER;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static void do_atomic_producer(void)<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>{<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    ovs_mutex_lock(&g_pvector_lock);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    if (g_index < 65536) {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>        g_my_data[g_index] = g_value;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>        pvector_insert(&g_atomic_test, (void *)&g_my_data[g_index], 0);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>        g_index++;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    } else {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>        for (int i = 0; i < g_index; i++) {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>            pvector_remove(&g_atomic_test, (void *)&g_my_data[i]);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>        }<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>        g_index = 0;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>        g_value++; //value can loops to zero;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    }<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    pvector_publish(&g_atomic_test);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    ovs_mutex_unlock(&g_pvector_lock);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>}<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static void do_atomic_consumer(void)<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>{<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    unsigned char *my_itr;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    unsigned char my_value;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    bool first = true;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    // ovs_mutex_lock(&g_pvector_lock);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    PVECTOR_FOR_EACH (my_itr, &g_atomic_test) {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>      if (first) {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>          my_value = *my_itr;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>          first = false;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>      } else if (*my_itr != my_value) {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>          VLOG_ERR("----my_itrator:%u, my_value:%u\n", *my_itr, my_value);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>          break;<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>      }<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    }<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>    // ovs_mutex_unlock(&g_pvector_lock);<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>}<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">><o:p> </o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>static void do_atomic_test(struct dp_netdev_pmd_thread *pmd)<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>{<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>   if (pmd->core_id == 1) {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>      do_atomic_producer();<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>   } else {<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>      do_atomic_consumer();<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>   }<o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D">>}</span><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" align="left" style="text-align:left"><span lang="EN-US" style="color:#1F497D"><o:p> </o:p></span></p>
</div>
</body>
</html>