-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Bug fix: Replace P2ALIGN with P2ALIGN_TYPED and delete P2ALIGN. #15940
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nice! I tested using a simple C program:
root@ubuntu-dev:~# cat test.c
#include <stdio.h>
#include <sys/types.h>
#include <stdint.h>
typedef unsigned int uint_t;
#define P2ALIGN(x, align) ((x) & -(align))
#define P2ALIGNNEW(x, align) ((x) & -((sizeof(x)>sizeof(align))?(typeof(x))(align):(align)))
int main()
{
uint64_t i64 = 0xabcdef00123456ff;
uint_t align = 128;
uint64_t aligned_value = P2ALIGN(i64, align);
uint64_t aligned_value_new = P2ALIGNNEW(i64, align);
printf("i64 = 0x%016lx\n", i64);
printf("P2ALIGN(0x%016lx, %u) = 0x%016lx\n", i64, align, aligned_value);
printf("P2ALIGNNEW(0x%016lx, %u) = 0x%016lx\n", i64, align, aligned_value_new);
return(0);
}
root@ubuntu-dev:~# ./test
i64 = 0xabcdef00123456ff
P2ALIGN(0xabcdef00123456ff, 128) = 0x0000000012345680
P2ALIGNNEW(0xabcdef00123456ff, 128) = 0xabcdef0012345680
eca2d33
to
d8312e4
Compare
I have updated my code to meet the OpenZFS code style requirements. |
Do you have any more suggestions? @youzhongyang We feel that this is a serious bug. It makes zfs inevitably hang on write requests without hardware problems when there are lots of files. In our case, the number of files per zfs exceeds 100 million. 3 of our 6 zfs hung in sequence, which made our 4+2 EC cluster down. We also tried remaking zpool and zfs, but the result remained the same. |
Just for a note, there is already a bunch of *_TYPED() macros, like P2ALIGN_TYPED(). |
@amotin Thanks for your reply.
The 1st option could accurately fix the bug, but it could not prevent future mistakes from occurring. The 2nd option could require developers to treat the type of Because options 1 and 2 require us to read and understand the code in different places, which could cause omissions or mistakes, we chose option 3 as our temporary patch. But in this PR, depending on your opinions and based on your review, options 1 and 2 can also be chosen. So, what do you think about these three options? |
I would suggest go with option #2, which requires you to review all instances of P2ALIGN and make changes accordingly. It's a bit of work, but it will make sure the same type of mistake won't be repeated in the future. |
d8312e4
to
52b6ead
Compare
@youzhongyang Thanks for your suggestion. |
It looks good to me. |
@chenqiuhao1997 could you rebase this and force update the PR. That will let us a get a clean CI run so this can be merged. |
9c2827e
to
52b6ead
Compare
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com>
52b6ead
to
2d11c79
Compare
@behlendorf the rebased commit 2d11c79 has been force pushed. Thanks for your follow up and view. |
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Youzhong Yang <yyang@mathworks.com> Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com> Closes openzfs#15940
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Youzhong Yang <yyang@mathworks.com> Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com> Closes openzfs#15940
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Youzhong Yang <yyang@mathworks.com> Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com> Closes #15940
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Cherry-picked-from: openzfs#16186 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Youzhong Yang <yyang@mathworks.com> Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com> Closes openzfs#15940 Signed-off-by: Gian-Carlo DeFazio <defazio1@llnl.gov>
One of our customers just hit this problem with billions of files in a wild. It would be good to merge this patch (may be without removal of the macros for compatibility) into 2.2.5 release. |
It's already queued up in the staging branch for 2.2.5, #16186. That version does drop the macros, is there some other known consumer of the macros? |
Thanks. I've already noticed that.
No. I'd just prefer to not break APIs in stable branches without need, but whatever. |
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Youzhong Yang <yyang@mathworks.com> Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com> Closes openzfs#15940
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Youzhong Yang <yyang@mathworks.com> Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com> Closes openzfs#15940 (cherry picked from commit 9edf6af)
In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Youzhong Yang <yyang@mathworks.com> Signed-off-by: Qiuhao Chen <chenqiuhao1997@gmail.com> Closes openzfs#15940 (cherry picked from commit 9edf6af)
Motivation and Context
Recently, our zfs-2.2.3-1 on 5.4.265-1.el8.elrepo.x86_64 always hung on write requests without hardware problems. Restarting server made no effect.
dmesg gave logs below:
After adding debug messages in codes, build and reinstall, we found our write requests hung in the for loop in
dmu_object_alloc_impl
. With more logs below and analyzing, we finally found this bug in P2ALIGN.In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case,
-(align)
would be a positive integer, which means high bits would be zero and finally stay zero after&
when align is converted to a larger integer type.Description
Replace P2ALIGN with P2ALIGN_TYPED and delete P2ALIGN.
How Has This Been Tested?
After fixed with this commit, our zfs has never hung again.
Types of changes
Checklist:
Signed-off-by
.