<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>This patch looks good to me.  Just a couple questions about object accounting...</div><div><br></div><div> brassow</div><br><div><div>On Jun 15, 2009, at 12:21 PM, <a href="mailto:heinzm@redhat.com">heinzm@redhat.com</a> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">+int dm_mem_cache_grow(struct dm_mem_cache_client *cl, unsigned objects)<br>+{<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>unsigned pages = objects * cl->chunks * cl->pages_per_chunk;<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>struct page_list *pl, *last;<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">       </span>BUG_ON(!pages);<br>+<span class="Apple-tab-span" style="white-space: pre; ">       </span>pl = alloc_cache_pages(pages);<br>+<span class="Apple-tab-span" style="white-space: pre; ">        </span>if (!pl)<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span>return -ENOMEM;<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>last = pl;<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>while (last->next)<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>last = last->next;<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span>spin_lock_irq(&cl->lock);<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span>last->next = cl->free_list;<br>+<span class="Apple-tab-span" style="white-space: pre; ">     </span>cl->free_list = pl;<br>+<span class="Apple-tab-span" style="white-space: pre; ">        </span>cl->free_pages += pages;<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>cl->total_pages += pages;<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>cl->objects++;<br></span></blockquote><div><br></div><div>Should this be 'cl->objects += objects'?</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">+<span class="Apple-tab-span" style="white-space: pre; ">      </span>spin_unlock_irq(&cl->lock);<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span>mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO);<br></span></blockquote><div><br></div><div>Do we need to check return value here?</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">+<span class="Apple-tab-span" style="white-space: pre; "> </span>return 0;<br>+}<br>+EXPORT_SYMBOL(dm_mem_cache_grow);<br>+<br>+/* Shrink a clients cache by an amount of pages */<br>+int dm_mem_cache_shrink(struct dm_mem_cache_client *cl, unsigned objects)<br>+{<br>+<span class="Apple-tab-span" style="white-space: pre; ">     </span>int r;<br>+<span class="Apple-tab-span" style="white-space: pre; ">        </span>unsigned pages = objects * cl->chunks * cl->pages_per_chunk, p = pages;<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span>unsigned long flags;<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>struct page_list *last = NULL, *pl, *pos;<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>BUG_ON(!pages);<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>spin_lock_irqsave(&cl->lock, flags);<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>pl = pos = cl->free_list;<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>while (p-- && pos->next) {<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>last = pos;<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span><span class="Apple-tab-span" style="white-space: pre; "> </span>pos = pos->next;<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>}<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>if (++p)<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span>r = -ENOMEM;<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>else {<br>+<span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; "> </span>r = 0;<br>+<span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; "> </span>cl->free_list = pos;<br>+<span class="Apple-tab-span" style="white-space: pre; ">       </span><span class="Apple-tab-span" style="white-space: pre; "> </span>cl->free_pages -= pages;<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span><span class="Apple-tab-span" style="white-space: pre; "> </span>cl->total_pages -= pages;<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span><span class="Apple-tab-span" style="white-space: pre; "> </span>cl->objects--;<br></span></blockquote><div><br></div><div>'cl->objects -= objects'?</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">+<span class="Apple-tab-span" style="white-space: pre; ">     </span><span class="Apple-tab-span" style="white-space: pre; "> </span>last->next = NULL;<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span>}<br>+<span class="Apple-tab-span" style="white-space: pre; ">     </span>spin_unlock_irqrestore(&cl->lock, flags);<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>if (!r) {<br>+<span class="Apple-tab-span" style="white-space: pre; ">     </span><span class="Apple-tab-span" style="white-space: pre; "> </span>free_cache_pages(pl);<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO);<br></span></blockquote><div><br></div><div>When shrinking, 'mempool_resize' will not fail... no need to check return value?</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">+<span class="Apple-tab-span" style="white-space: pre; ">       </span>}<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>return r;<br>+}<br>+EXPORT_SYMBOL(dm_mem_cache_shrink);<br>+<br>+/*<br>+ * Allocate/free a memory object<br>+ *<br>+ * Can be called from interrupt context<br>+ */<br>+struct dm_mem_cache_object *dm_mem_cache_alloc(struct dm_mem_cache_client *cl)<br>+{<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span>int r = 0;<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>unsigned pages = cl->chunks * cl->pages_per_chunk;<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span>unsigned long flags;<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>struct dm_mem_cache_object *obj;<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>obj = mempool_alloc(cl->objs_pool, GFP_NOIO);<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span>if (!obj)<br>+<span class="Apple-tab-span" style="white-space: pre; ">     </span><span class="Apple-tab-span" style="white-space: pre; "> </span>return ERR_PTR(-ENOMEM);<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>spin_lock_irqsave(&cl->lock, flags);<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>if (pages > cl->free_pages)<br>+<span class="Apple-tab-span" style="white-space: pre; ">     </span><span class="Apple-tab-span" style="white-space: pre; "> </span>r = -ENOMEM;<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>else<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span><span class="Apple-tab-span" style="white-space: pre; "> </span>cl->free_pages -= pages;<br>+<span class="Apple-tab-span" style="white-space: pre; ">   </span>spin_unlock_irqrestore(&cl->lock, flags);<br></span></blockquote><div><br></div><div>It's not important, but 'free_chunks' adjusts the 'cl->free_pages' count for us...  That made me look for where 'cl->free_pages' was adjusted in 'alloc_chunks', but that is done here.  Could we push this critical section into alloc_chunks and then just check the return code of that?</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">+<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>if (r) {<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span>mempool_free(obj, cl->objs_pool);<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span><span class="Apple-tab-span" style="white-space: pre; "> </span>return ERR_PTR(r);<br>+<span class="Apple-tab-span" style="white-space: pre; ">    </span>}<br>+<br>+<span class="Apple-tab-span" style="white-space: pre; ">  </span>alloc_chunks(cl, obj);<br>+<span class="Apple-tab-span" style="white-space: pre; ">        </span>return obj;<br>+}<br>+EXPORT_SYMBOL(dm_mem_cache_alloc);<br>+<br>+void dm_mem_cache_free(struct dm_mem_cache_client *cl,<br>+<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-converted-space"> </span>      struct dm_mem_cache_object *obj)<br>+{<br>+<span class="Apple-tab-span" style="white-space: pre; ">       </span>free_chunks(cl, obj);<br>+<span class="Apple-tab-span" style="white-space: pre; "> </span>mempool_free(obj, cl->objs_pool);<br>+}<br>+EXPORT_SYMBOL(dm_mem_cache_free);<br>+<br>+MODULE_DESCRIPTION(DM_NAME " dm memory cache");<br>+MODULE_AUTHOR("Heinz Mauelshagen <<a href="mailto:hjm@redhat.com">hjm@redhat.com</a>>");<br>+MODULE_LICENSE("GPL");<br></span></blockquote></div><br><div><br></div></body></html>