Skip to content

bpo-43441: fix [Subinterpreters]: global variable next_version_tag cause method cache bug #24822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 13, 2021
Merged

bpo-43441: fix [Subinterpreters]: global variable next_version_tag cause method cache bug #24822

merged 2 commits into from
Mar 13, 2021

Conversation

JunyiXie
Copy link
Contributor

@JunyiXie JunyiXie commented Mar 11, 2021

under building Python with --with-experimental-isolated-subinterpreters

when sub interpreter finalize.
_PyType_ClearCache set next_version_tag = 0.

Type shared between interpreters.
another interpreter assign_version_tag "1" for a type, the type is first assign.

the dealloc interpreter had assign_version_tag "1" for another type.

now, two different type has same version tag. it cause method cache wrong.

static unsigned int
_PyType_ClearCache(struct type_cache *cache)
{
#if MCACHE_STATS
    size_t total = cache->hits + cache->collisions + cache->misses;
    fprintf(stderr, "-- Method cache hits        = %zd (%d%%)\n",
            cache->hits, (int) (100.0 * cache->hits / total));
    fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n",
            cache->misses, (int) (100.0 * cache->misses / total));
    fprintf(stderr, "-- Method cache collisions  = %zd (%d%%)\n",
            cache->collisions, (int) (100.0 * cache->collisions / total));
    fprintf(stderr, "-- Method cache size        = %zd KiB\n",
            sizeof(cache->hashtable) / 1024);
#endif

    unsigned int cur_version_tag = next_version_tag - 1;
    next_version_tag = 0;
    type_cache_clear(cache, 0);

    return cur_version_tag;
}

https://bugs.python.org/issue43441

@JunyiXie JunyiXie requested a review from markshannon as a code owner March 11, 2021 10:16
@JunyiXie JunyiXie changed the title issue43441: fix [Subinterpreters]: global variable next_version_tag c… issue43441: fix [Subinterpreters]: global variable next_version_tag cause method cache bug Mar 11, 2021
@JunyiXie JunyiXie changed the title issue43441: fix [Subinterpreters]: global variable next_version_tag cause method cache bug bpo-43441: fix [Subinterpreters]: global variable next_version_tag cause method cache bug Mar 11, 2021
@corona10 corona10 requested a review from vstinner March 11, 2021 12:34
@@ -285,9 +285,9 @@ PyType_ClearCache(void)
void
_PyType_Fini(PyInterpreterState *interp)
{
_PyType_ClearCache(&interp->type_cache);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change leaks memory: type_cache_clear() clears objects and should be done in subinterpreters.

I suggest to pass interp to _PyType_ClearCache() and check _Py_IsMainInterpreter(interp) in this function to decide if next_version_tag must be modified or not.

Copy link
Contributor Author

@JunyiXie JunyiXie Mar 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your review, it is very reasonable. I have made the changes as you suggested.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

And if you don't make the requested changes, you will be poked with soft cushions!

@JunyiXie
Copy link
Contributor Author

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@vstinner: please review the changes made to this pull request.

@bedevere-bot bedevere-bot requested a review from vstinner March 11, 2021 13:25
@@ -0,0 +1 @@
under building Python with --with-experimental-isolated-subinterpreters, fix method cache mess cause by global variable next_version_tag and sub interpreter destory clear type method cache.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the NEWS entry. I would prefer to keep --with-experimental-isolated-subinterpreters feature secret on purpose. It's still experimental (and broken).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thanks for the hint.

@JunyiXie
Copy link
Contributor Author

JunyiXie commented Mar 12, 2021

@vstinner Thank you for your code review, I have removed the news. But I don't know how to make bedevere/news — No news entry in Misc/NEWS.d/next/ or "skip news" label found check success.

@@ -252,7 +252,7 @@ _PyType_InitCache(PyInterpreterState *interp)


static unsigned int
_PyType_ClearCache(struct type_cache *cache)
_PyType_ClearCache(PyInterpreterState *interp, struct type_cache *cache)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, the cache parameter sounds redundant. Please remove it and get the cache with:

struct type_cache *cache = &interp->type_cache;

So you can remove struct type_cache *cache = get_type_cache(); in PyType_ClearCache().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks vstinner, good suggestion.

@JunyiXie
Copy link
Contributor Author

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@vstinner: please review the changes made to this pull request.

@bedevere-bot bedevere-bot requested a review from vstinner March 12, 2021 12:48
@@ -267,7 +268,10 @@ _PyType_ClearCache(struct type_cache *cache)
#endif

unsigned int cur_version_tag = next_version_tag - 1;
next_version_tag = 0;
if (_Py_IsMainInterpreter(interp)) {
next_version_tag = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be safer to have a per-interpreter next_version_tag. The problem is that there are still many static types which are shared between interpreters :-/ You may add a comment explaining that:

// bpo-42745: next_version_tag remains shared by all interpreters because of static types

Or put the comment on the variable definition:

// Used to set PyTypeObject.tp_version_tag
static unsigned int next_version_tag = 0;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, ok i added

@JunyiXie
Copy link
Contributor Author

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@vstinner: please review the changes made to this pull request.

@bedevere-bot bedevere-bot requested a review from vstinner March 12, 2021 16:53
@vstinner vstinner merged commit 75048c8 into python:master Mar 13, 2021
@vstinner
Copy link
Member

I pushed my last requested change and I merged your PR, thanks for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants