<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<div>cmpxchg be replaced by some simple c sentance?<br>
otherwise we have to remove __rcu of chian->prev.<br>
<br>
-David<br>
<br>
-------- Original Message --------<br>
Subject: Re: [PATCH 1/9] dma-buf: add new dma_fence_chain container v6<br>
From: Christian König <br>
To: "Zhou, David(ChunMing)" ,kbuild test robot ,"Zhou, David(ChunMing)" <br>
CC: kbuild-all@01.org,dri-devel@lists.freedesktop.org,amd-gfx@lists.freedesktop.org,lionel.g.landwerlin@intel.com,jason@jlekstrand.net,"Koenig, Christian" ,"Hector, Tobias"
<br>
<br>
</div>
<font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi David,<br>
<br>
For the cmpxchg() case I of hand don't know either. Looks like so far <br>
nobody has used cmpxchg() with rcu protected structures.<br>
<br>
The other cases should be replaced by RCU_INIT_POINTER() or <br>
rcu_dereference_protected(.., true);<br>
<br>
Regards,<br>
Christian.<br>
<br>
Am 21.03.19 um 07:34 schrieb zhoucm1:<br>
> Hi Lionel and Christian,<br>
><br>
> Below is robot report for chain->prev, which was added __rcu as you <br>
> suggested.<br>
><br>
> How to fix this line "tmp = cmpxchg(&chain->prev, prev, replacement); "?<br>
> I checked kernel header file, seems it has no cmpxchg for rcu.<br>
><br>
> Any suggestion to fix this robot report?<br>
><br>
> Thanks,<br>
> -David<br>
><br>
> On 2019年03月21日 08:24, kbuild test robot wrote:<br>
>> Hi Chunming,<br>
>><br>
>> I love your patch! Perhaps something to improve:<br>
>><br>
>> [auto build test WARNING on linus/master]<br>
>> [also build test WARNING on v5.1-rc1 next-20190320]<br>
>> [if your patch is applied to the wrong git tree, please drop us a <br>
>> note to help improve the system]<br>
>><br>
>> url: <br>
>> <a href="https://github.com/0day-ci/linux/commits/Chunming-Zhou/dma-buf-add-new-dma_fence_chain-container-v6/20190320-223607">
https://github.com/0day-ci/linux/commits/Chunming-Zhou/dma-buf-add-new-dma_fence_chain-container-v6/20190320-223607</a><br>
>> reproduce:<br>
>>          # apt-get install sparse<br>
>>          make ARCH=x86_64 allmodconfig<br>
>>          make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'<br>
>><br>
>><br>
>> sparse warnings: (new ones prefixed by >>)<br>
>><br>
>>>> drivers/dma-buf/dma-fence-chain.c:73:23: sparse: incorrect type in <br>
>>>> initializer (different address spaces) @@    expected struct <br>
>>>> dma_fence [noderef] <asn:4>*__old @@    got  dma_fence [noderef] <br>
>>>> <asn:4>*__old @@<br>
>>     drivers/dma-buf/dma-fence-chain.c:73:23:    expected struct <br>
>> dma_fence [noderef] <asn:4>*__old<br>
>>     drivers/dma-buf/dma-fence-chain.c:73:23:    got struct dma_fence <br>
>> *[assigned] prev<br>
>>>> drivers/dma-buf/dma-fence-chain.c:73:23: sparse: incorrect type in <br>
>>>> initializer (different address spaces) @@    expected struct <br>
>>>> dma_fence [noderef] <asn:4>*__new @@    got  dma_fence [noderef] <br>
>>>> <asn:4>*__new @@<br>
>>     drivers/dma-buf/dma-fence-chain.c:73:23:    expected struct <br>
>> dma_fence [noderef] <asn:4>*__new<br>
>>     drivers/dma-buf/dma-fence-chain.c:73:23:    got struct dma_fence <br>
>> *[assigned] replacement<br>
>>>> drivers/dma-buf/dma-fence-chain.c:73:21: sparse: incorrect type in <br>
>>>> assignment (different address spaces) @@    expected struct <br>
>>>> dma_fence *tmp @@    got struct dma_fence [noderef] <struct <br>
>>>> dma_fence *tmp @@<br>
>>     drivers/dma-buf/dma-fence-chain.c:73:21:    expected struct <br>
>> dma_fence *tmp<br>
>>     drivers/dma-buf/dma-fence-chain.c:73:21:    got struct dma_fence <br>
>> [noderef] <asn:4>*[assigned] __ret<br>
>>>> drivers/dma-buf/dma-fence-chain.c:190:28: sparse: incorrect type in <br>
>>>> argument 1 (different address spaces) @@    expected struct <br>
>>>> dma_fence *fence @@    got struct dma_fence struct dma_fence *fence @@<br>
>>     drivers/dma-buf/dma-fence-chain.c:190:28:    expected struct <br>
>> dma_fence *fence<br>
>>     drivers/dma-buf/dma-fence-chain.c:190:28:    got struct dma_fence <br>
>> [noderef] <asn:4>*prev<br>
>>>> drivers/dma-buf/dma-fence-chain.c:222:21: sparse: incorrect type in <br>
>>>> assignment (different address spaces) @@    expected struct <br>
>>>> dma_fence [noderef] <asn:4>*prev @@    got [noderef] <asn:4>*prev @@<br>
>>     drivers/dma-buf/dma-fence-chain.c:222:21:    expected struct <br>
>> dma_fence [noderef] <asn:4>*prev<br>
>>     drivers/dma-buf/dma-fence-chain.c:222:21:    got struct dma_fence <br>
>> *prev<br>
>>     drivers/dma-buf/dma-fence-chain.c:235:33: sparse: expression <br>
>> using sizeof(void)<br>
>>     drivers/dma-buf/dma-fence-chain.c:235:33: sparse: expression <br>
>> using sizeof(void)<br>
>><br>
>> vim +73 drivers/dma-buf/dma-fence-chain.c<br>
>><br>
>>      38<br>
>>      39    /**<br>
>>      40     * dma_fence_chain_walk - chain walking function<br>
>>      41     * @fence: current chain node<br>
>>      42     *<br>
>>      43     * Walk the chain to the next node. Returns the next fence <br>
>> or NULL if we are at<br>
>>      44     * the end of the chain. Garbage collects chain nodes <br>
>> which are already<br>
>>      45     * signaled.<br>
>>      46     */<br>
>>      47    struct dma_fence *dma_fence_chain_walk(struct dma_fence <br>
>> *fence)<br>
>>      48    {<br>
>>      49        struct dma_fence_chain *chain, *prev_chain;<br>
>>      50        struct dma_fence *prev, *replacement, *tmp;<br>
>>      51<br>
>>      52        chain = to_dma_fence_chain(fence);<br>
>>      53        if (!chain) {<br>
>>      54            dma_fence_put(fence);<br>
>>      55            return NULL;<br>
>>      56        }<br>
>>      57<br>
>>      58        while ((prev = dma_fence_chain_get_prev(chain))) {<br>
>>      59<br>
>>      60            prev_chain = to_dma_fence_chain(prev);<br>
>>      61            if (prev_chain) {<br>
>>      62                if (!dma_fence_is_signaled(prev_chain->fence))<br>
>>      63                    break;<br>
>>      64<br>
>>      65                replacement = <br>
>> dma_fence_chain_get_prev(prev_chain);<br>
>>      66            } else {<br>
>>      67                if (!dma_fence_is_signaled(prev))<br>
>>      68                    break;<br>
>>      69<br>
>>      70                replacement = NULL;<br>
>>      71            }<br>
>>      72<br>
>>    > 73            tmp = cmpxchg(&chain->prev, prev, replacement);<br>
>>      74            if (tmp == prev)<br>
>>      75                dma_fence_put(tmp);<br>
>>      76            else<br>
>>      77                dma_fence_put(replacement);<br>
>>      78            dma_fence_put(prev);<br>
>>      79        }<br>
>>      80<br>
>>      81        dma_fence_put(fence);<br>
>>      82        return prev;<br>
>>      83    }<br>
>>      84    EXPORT_SYMBOL(dma_fence_chain_walk);<br>
>>      85<br>
>>      86    /**<br>
>>      87     * dma_fence_chain_find_seqno - find fence chain node by <br>
>> seqno<br>
>>      88     * @pfence: pointer to the chain node where to start<br>
>>      89     * @seqno: the sequence number to search for<br>
>>      90     *<br>
>>      91     * Advance the fence pointer to the chain node which will <br>
>> signal this sequence<br>
>>      92     * number. If no sequence number is provided then this is <br>
>> a no-op.<br>
>>      93     *<br>
>>      94     * Returns EINVAL if the fence is not a chain node or the <br>
>> sequence number has<br>
>>      95     * not yet advanced far enough.<br>
>>      96     */<br>
>>      97    int dma_fence_chain_find_seqno(struct dma_fence **pfence, <br>
>> uint64_t seqno)<br>
>>      98    {<br>
>>      99        struct dma_fence_chain *chain;<br>
>>     100<br>
>>     101        if (!seqno)<br>
>>     102            return 0;<br>
>>     103<br>
>>     104        chain = to_dma_fence_chain(*pfence);<br>
>>     105        if (!chain || chain->base.seqno < seqno)<br>
>>     106            return -EINVAL;<br>
>>     107<br>
>>     108        dma_fence_chain_for_each(*pfence, &chain->base) {<br>
>>     109            if ((*pfence)->context != chain->base.context ||<br>
>>     110 to_dma_fence_chain(*pfence)->prev_seqno < seqno)<br>
>>     111                break;<br>
>>     112        }<br>
>>     113        dma_fence_put(&chain->base);<br>
>>     114<br>
>>     115        return 0;<br>
>>     116    }<br>
>>     117    EXPORT_SYMBOL(dma_fence_chain_find_seqno);<br>
>>     118<br>
>>     119    static const char *dma_fence_chain_get_driver_name(struct <br>
>> dma_fence *fence)<br>
>>     120    {<br>
>>     121            return "dma_fence_chain";<br>
>>     122    }<br>
>>     123<br>
>>     124    static const char <br>
>> *dma_fence_chain_get_timeline_name(struct dma_fence *fence)<br>
>>     125    {<br>
>>     126            return "unbound";<br>
>>     127    }<br>
>>     128<br>
>>     129    static void dma_fence_chain_irq_work(struct irq_work *work)<br>
>>     130    {<br>
>>     131        struct dma_fence_chain *chain;<br>
>>     132<br>
>>     133        chain = container_of(work, typeof(*chain), work);<br>
>>     134<br>
>>     135        /* Try to rearm the callback */<br>
>>     136        if (!dma_fence_chain_enable_signaling(&chain->base))<br>
>>     137            /* Ok, we are done. No more unsignaled fences left */<br>
>>     138            dma_fence_signal(&chain->base);<br>
>>     139        dma_fence_put(&chain->base);<br>
>>     140    }<br>
>>     141<br>
>>     142    static void dma_fence_chain_cb(struct dma_fence *f, struct <br>
>> dma_fence_cb *cb)<br>
>>     143    {<br>
>>     144        struct dma_fence_chain *chain;<br>
>>     145<br>
>>     146        chain = container_of(cb, typeof(*chain), cb);<br>
>>     147        irq_work_queue(&chain->work);<br>
>>     148        dma_fence_put(f);<br>
>>     149    }<br>
>>     150<br>
>>     151    static bool dma_fence_chain_enable_signaling(struct <br>
>> dma_fence *fence)<br>
>>     152    {<br>
>>     153        struct dma_fence_chain *head = to_dma_fence_chain(fence);<br>
>>     154<br>
>>     155        dma_fence_get(&head->base);<br>
>>     156        dma_fence_chain_for_each(fence, &head->base) {<br>
>>     157            struct dma_fence_chain *chain = <br>
>> to_dma_fence_chain(fence);<br>
>>     158            struct dma_fence *f = chain ? chain->fence : fence;<br>
>>     159<br>
>>     160            dma_fence_get(f);<br>
>>     161            if (!dma_fence_add_callback(f, &head->cb, <br>
>> dma_fence_chain_cb)) {<br>
>>     162                dma_fence_put(fence);<br>
>>     163                return true;<br>
>>     164            }<br>
>>     165            dma_fence_put(f);<br>
>>     166        }<br>
>>     167        dma_fence_put(&head->base);<br>
>>     168        return false;<br>
>>     169    }<br>
>>     170<br>
>>     171    static bool dma_fence_chain_signaled(struct dma_fence *fence)<br>
>>     172    {<br>
>>     173        dma_fence_chain_for_each(fence, fence) {<br>
>>     174            struct dma_fence_chain *chain = <br>
>> to_dma_fence_chain(fence);<br>
>>     175            struct dma_fence *f = chain ? chain->fence : fence;<br>
>>     176<br>
>>     177            if (!dma_fence_is_signaled(f)) {<br>
>>     178                dma_fence_put(fence);<br>
>>     179                return false;<br>
>>     180            }<br>
>>     181        }<br>
>>     182<br>
>>     183        return true;<br>
>>     184    }<br>
>>     185<br>
>>     186    static void dma_fence_chain_release(struct dma_fence *fence)<br>
>>     187    {<br>
>>     188        struct dma_fence_chain *chain = <br>
>> to_dma_fence_chain(fence);<br>
>>     189<br>
>>   > 190        dma_fence_put(chain->prev);<br>
>>     191        dma_fence_put(chain->fence);<br>
>>     192        dma_fence_free(fence);<br>
>>     193    }<br>
>>     194<br>
>>     195    const struct dma_fence_ops dma_fence_chain_ops = {<br>
>>     196        .get_driver_name = dma_fence_chain_get_driver_name,<br>
>>     197        .get_timeline_name = dma_fence_chain_get_timeline_name,<br>
>>     198        .enable_signaling = dma_fence_chain_enable_signaling,<br>
>>     199        .signaled = dma_fence_chain_signaled,<br>
>>     200        .release = dma_fence_chain_release,<br>
>>     201    };<br>
>>     202    EXPORT_SYMBOL(dma_fence_chain_ops);<br>
>>     203<br>
>>     204    /**<br>
>>     205     * dma_fence_chain_init - initialize a fence chain<br>
>>     206     * @chain: the chain node to initialize<br>
>>     207     * @prev: the previous fence<br>
>>     208     * @fence: the current fence<br>
>>     209     *<br>
>>     210     * Initialize a new chain node and either start a new <br>
>> chain or add the node to<br>
>>     211     * the existing chain of the previous fence.<br>
>>     212     */<br>
>>     213    void dma_fence_chain_init(struct dma_fence_chain *chain,<br>
>>     214                  struct dma_fence *prev,<br>
>>     215                  struct dma_fence *fence,<br>
>>     216                  uint64_t seqno)<br>
>>     217    {<br>
>>     218        struct dma_fence_chain *prev_chain = <br>
>> to_dma_fence_chain(prev);<br>
>>     219        uint64_t context;<br>
>>     220<br>
>>     221        spin_lock_init(&chain->lock);<br>
>>   > 222        chain->prev = prev;<br>
>><br>
>> ---<br>
>> 0-DAY kernel test infrastructure                Open Source <br>
>> Technology Center<br>
>> <a href="https://lists.01.org/pipermail/kbuild-all">https://lists.01.org/pipermail/kbuild-all</a> Intel Corporation<br>
><br>
<br>
</div>
</span></font>
</body>
</html>