It is certainly true that the OS does some readahead of its own. However, we found that doing manual readahead provided a performance boost in many scenarios, especially ones involving long sequential reads. That's why the Datanode currently does readahead by default. These settings should be honored when using short-circuit local reads, so that the behavior is consistent and configurable.
Most of HBase's reads are random reads. Readahead will not benefit random reads. The current readahead code in the DN will not do readahead when small, random reads are being done, and we should follow suit in BlockReaderLocal. I do think HBase will see some benefit when doing long scans, and doing compactions.
As you mentioned, it's true that readahead is not always a win when memory pressure is extremely high. However, when memory pressure is so high that sections that got read ahead have to be purged prior to use, the system usually has other problems that make it unstable and essentially unusable, like the OOM killer triggering.