On 8/15/19 7:00 PM, Alexander Duyck wrote: > On Thu, Aug 15, 2019 at 12:23 PM Nitesh Narayan Lal <nitesh@xxxxxxxxxx> wrote: [...] >>>>>>> +} >>>>>>> + >>>>>>> +/** >>>>>>> + * __page_reporting_enqueue - tracks the freed page in the respective zone's >>>>>>> + * bitmap and enqueues a new page reporting job to the workqueue if possible. >>>>>>> + */ >>>>>>> +void __page_reporting_enqueue(struct page *page) >>>>>>> +{ >>>>>>> + struct page_reporting_config *phconf; >>>>>>> + struct zone *zone; >>>>>>> + >>>>>>> + rcu_read_lock(); >>>>>>> + /* >>>>>>> + * We should not process this page if either page reporting is not >>>>>>> + * yet completely enabled or it has been disabled by the backend. >>>>>>> + */ >>>>>>> + phconf = rcu_dereference(page_reporting_conf); >>>>>>> + if (!phconf) >>>>>>> + return; >>>>>>> + >>>>>>> + zone = page_zone(page); >>>>>>> + bitmap_set_bit(page, zone); >>>>>>> + >>>>>>> + /* >>>>>>> + * We should not enqueue a job if a previously enqueued reporting work >>>>>>> + * is in progress or we don't have enough free pages in the zone. >>>>>>> + */ >>>>>>> + if (atomic_read(&zone->free_pages) >= phconf->max_pages && >>>>>>> + !atomic_cmpxchg(&phconf->refcnt, 0, 1)) >>>>>> This doesn't make any sense to me. Why are you only incrementing the >>>>>> refcount if it is zero? Combining this with the assignment above, this >>>>>> isn't really a refcnt. It is just an oversized bitflag. >>>>> The intent for having an extra variable was to ensure that at a time only one >>>>> reporting job is enqueued. I do agree that for that purpose I really don't need >>>>> a reference counter and I should have used something like bool >>>>> 'page_hinting_active'. But with bool, I think there could be a possible chance >>>>> of race. Maybe I should rename this variable and keep it as atomic. >>>>> Any thoughts? >>>> You could just use a bitflag to achieve what you are doing here. That >>>> is the primary use case for many of the test_and_set_bit type >>>> operations. However one issue with doing it as a bitflag is that you >>>> have no way of telling that you took care of all requesters. >>> I think you are right, I might end up missing on certain reporting >>> opportunities in some special cases. Specifically when the pages which are >>> part of this new reporting request belongs to a section of the bitmap which >>> has already been scanned. Although, I have failed to reproduce this kind of >>> situation in an actual setup. >>> >>>> That is >>>> where having an actual reference count comes in handy as you know >>>> exactly how many zones are requesting to be reported on. >>> True. >>> >>>>>> Also I am pretty sure this results in the opportunity to miss pages >>>>>> because there is nothing to prevent you from possibly missing a ton of >>>>>> pages you could hint on if a large number of pages are pushed out all >>>>>> at once and then the system goes idle in terms of memory allocation >>>>>> and freeing. >>>>> I was looking at how you are enqueuing/processing reporting jobs for each zone. >>>>> I am wondering if I should also consider something on similar lines as having >>>>> that I might be able to address the concern which you have raised above. But it >>>>> would also mean that I have to add an additional flag in the zone_flags. :) >>>> You could do it either in the zone or outside the zone as yet another >>>> bitmap. I decided to put the flags inside the zone because there was a >>>> number of free bits there and it should be faster since we were >>>> already using the zone structure. >>> There are two possibilities which could happen while I am reporting: >>> 1. Another request might come in for a different zone. >>> 2. Another request could come in for the same zone and the pages belong to a >>> section of the bitmap which has already been scanned. >>> >>> Having a per zone flag to indicate reporting status will solve the first >>> issue and to an extent the second as well. Having refcnt will possibly solve >>> both of them. What I am wondering about is that in my case I could easily >>> impact the performance negatively by performing more bitmap scanning. >>> >>> >> I realized that it may not be possible for me to directly adopt either refcnt >> or zone flags just because of the way I have page reporting setup right now. >> >> For now, I will just replace the refcnt with a bitflag as that should work >> for most of the cases. Nevertheless, I will also keep looking for a better way. > If nothing else something you could consider is a refcnt for the > number of bits you have set in your bitfield. Then all you would need > to be doing is replace the cmpxchg with just a atomic_fetch_inc and > what you would need to do is have your worker thread track how many > bits it has cleared and subtract that from the refcnt at the end. Thanks, I will think about this suggestion as well. Based on your previous suggestion and what you have already proposed in your series I can think of a way to atleast ensure reporting for zones freeing pages after getting scanned in wq. (In case I decide to go ahead with this approach I will mention that this change is based on your series. Please do let me know if there is a better way to give credit) However, a situation where the same zone is reporting pages from the bitmap section already scanned with zero freeing activity on other zones, may not be entirely handled. In any case, I think what I have in my mind will be better than what I have right now. I will try to implement and test it to see if it can actually work. -- Thanks Nitesh